문제

대부분의 성숙한 C++ 프로젝트에는 고유한 기능이 있는 것 같습니다. 반사 및 속성 시스템, 즉 문자열로 액세스할 수 있고 자동으로 직렬화할 수 있는 속성을 정의하기 위한 것입니다.내가 참여한 적어도 많은 C++ 프로젝트는 바퀴를 재발명하다.

혹시 아시나요? 좋은 오픈소스 라이브러리 리플렉션 및 속성 컨테이너를 지원하는 C++의 경우 특히 다음과 같습니다.

  • 매크로를 통해 RTTI 및 속성 정의
  • 코드를 통해 RTTI 및 속성에 액세스
  • 속성의 자동 직렬화
  • 속성 수정 듣기(예:값이 변경됨)
도움이 되었습니까?

해결책

아래 두 가지 도구를 살펴볼 수 있습니다.나는 둘 중 하나를 사용해 본 적이 없기 때문에 그것이 얼마나 (비)실용적인지 말할 수 없습니다.

XRTTI:

Xrtti는 C++의 표준 런타임 유형 시스템을 확장하여 이러한 클래스와 해당 멤버를 조작하는 클래스 및 메서드에 대한 훨씬 더 풍부한 반영 정보 세트를 제공하는 도구이자 함께 제공되는 C++ 라이브러리입니다.

오픈C++:

OpenC++는 C++ 프런트엔드 라이브러리(렉서+파서+DOM/MOP)이자 소스-소스 변환기입니다.OpenC++를 사용하면 C++ 언어 도구, 확장, 도메인별 컴파일러 최적화 및 런타임 메타객체 프로토콜을 개발할 수 있습니다.

다른 팁

C++가 Reflection을 만났을 때 얻을 수 있는 결과는 다음과 같습니다.

C++ meets Reflection

무엇을 선택하든 끔찍한 매크로, 디버깅하기 어려운 코드 또는 이상한 빌드 단계가 있을 수 있습니다.한 시스템이 DevStudio의 PDB 파일에서 직렬화 코드를 자동으로 생성하는 것을 보았습니다.

하지만 소규모 프로젝트의 경우 저장/로드 기능을 작성하는 것(또는 스트리밍 연산자를 사용하는 것)이 더 쉬울 것입니다.실제로 이는 대규모 프로젝트에도 적용될 수 있습니다. 무슨 일이 일어나고 있는지 분명하며 구조가 변경되면 일반적으로 코드를 변경해야 합니다.

완전히 다른 접근 방식을 사용하여 C++에서 리플렉션을 제공하는 새로운 프로젝트가 있습니다. 캠프. https://github.com/tegesoft/camp

CAMP는 사전 컴파일러인 클래스/속성/함수/...를 사용하지 않습니다.Boost.python 또는 luabind와 유사한 구문을 사용하여 수동으로 선언됩니다.물론 사람들은 원하는 경우 gccxml 또는 open-C++와 같은 사전 컴파일러를 사용하여 이 선언을 생성할 수 있습니다.

이는 순수 C++ 및 부스트 헤더만을 기반으로 하며 템플릿 메타 프로그래밍의 힘 덕분에 모든 종류의 바인딩 가능한 엔터티를 지원합니다(예를 들어 상속 및 이상한 생성자는 문제가 되지 않습니다).

MIT 라이선스(이전 LGPL)에 따라 배포됩니다.

꽤 오랫동안 이런 것들을 살펴봤는데, 굉장히 무거운 편인 것 같아요.상속을 사용하거나 이상한 생성자를 사용하는 등의 작업을 방해할 수 있습니다.결국 편리함보다는 너무 큰 부담이 되고 말았습니다.

내가 지금 사용하는 멤버 노출을 위한 이 접근 방식은 매우 간단하며 예를 들어 직렬화를 위한 클래스를 탐색하거나 "x"라는 모든 필드를 0으로 설정할 수 있습니다.또한 정적으로 결정되므로 매우 빠릅니다.빌드 프로세스를 망칠 염려가 있는 라이브러리 코드 또는 코드 생성 레이어가 없습니다.이는 중첩 유형의 계층 구조로 일반화됩니다.

이러한 내용 중 일부를 자동으로 작성하려면 일부 매크로를 사용하여 편집기를 설정하세요.

struct point
{
     int x;
     int y;

     // add this to your classes
     template <typename Visitor>
     void visit(Visitor v)
     {
         v->visit(x, "x"); 
         v->visit(y, "y");
     }
};


/** Outputs any type to standard output in key=value format */
struct stdout_visitor
{
     template <typename T>
     void visit(const T& rhs)
     {
         rhs.visit(this);
     }

     template <typename Scalar>
     void visit (const Scalar& s, const char* name)
     {
          std::cout << name << " = " << s << " ";
     }
}

이것도 잠시 살펴봤습니다.현재 가장 쉬운 해결책은 다음과 같습니다. BOOST_FUSION_ADAPT_STRUCT.실제로 라이브러리/헤더가 있으면 다음과 같이 구조체 필드를 BOOST_FUSION_ADAPT_STRUCT() 매크로에 추가하기만 하면 됩니다. 코드의 마지막 부분은 다음과 같습니다.예, 많은 사람들이 언급한 제한 사항이 있습니다.그리고 청취자를 직접 지원하지 않습니다.

제가 조사한 다른 유망한 솔루션은 다음과 같습니다.

  • 그러나 CAMP와 XRTTI/gccxml은 둘 다 외부 도구 종속성을 프로젝트에 적용하는 데 장애물이 되는 것 같습니다.
  • 몇 년 전에 나는 Perl을 사용했습니다. c2ph/pstruct 출력에서 메타 정보를 덤프하려면 gcc -gstabs, 덜 방해적이지만 나에게는 완벽하게 작동했지만 더 많은 작업이 필요합니다.

Boost/__cxa 접근 방식과 관련하여 모든 작은 세부 사항을 파악한 후에는 구조체 또는 필드를 추가/변경하는 것이 유지 관리가 간단합니다.우리는 현재 이를 dbus 위에 사용자 정의 유형 바인딩 레이어를 구축하고, API를 직렬화하고, 관리 개체 서비스 하위 시스템에 대한 전송/RPC 세부 정보를 숨기는 데 사용하고 있습니다.

일반적인 것은 아니지만 QT는 메타 컴파일러를 통해 이를 지원하며 GPL입니다.QT 사람들과 이야기하면서 제가 이해한 바는 이것이 순수 C++에서는 불가능하므로 moc가 필요하다는 것입니다.

이는 일반적으로 C++ 언어의 악명 높은 약점입니다. 왜냐하면 리플렉션 구현을 이식 가능하고 가치 있게 만들기 위해 표준화해야 하는 사항이 표준이 아니기 때문입니다.호출 규칙, 객체 레이아웃, 기호 맹글링 등이 떠오르지만 다른 것들도 있습니다.

표준의 방향이 부족하다는 것은 컴파일러 구현자가 일부 작업을 다르게 수행한다는 것을 의미하며, 이는 이식 가능한 리플렉션 라이브러리를 작성하려는 동기를 가진 사람이 거의 없다는 것을 의미합니다. 이는 리플렉션이 필요한 사람들이 휠을 다시 발명해야 한다는 것을 의미하지만 단지 충분할 뿐입니다. 그들이 필요한 것을 위해.이런 일이 발생합니다 무한히, 여기 있습니다.

자동 내성/반영 툴킷.Qt와 같은 메타 컴파일러를 사용하고 메타 정보를 객체 파일에 직접 추가하십시오.직관적이고 사용하기 쉽습니다.외부 종속성이 없습니다.심지어 자동으로 std::string을 반영한 다음 스크립트에서 사용하도록 허용합니다.방문하시기 바랍니다 IDK

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top