1

저는 고성능 C++ 클래스를 공유 라이브러리로 컴파일 한 얇은 C 계층으로 래핑 한 다음 Python과 같은 다른 프로그래밍 언어로로드하는 기술을 종종 사용합니다.C++ 바이너리 코드가 네이티브 C 인터페이스를 통해 이식 가능할 수 있습니까? 한계는 무엇입니까?

여기저기서 읽으면서이 기능이 작동하는 유일한 요구 사항은 에만 기본 유형 또는이 유형의 구조체 인 인터페이스를 사용하는 것임을 이해합니다. (따라서, intlongs, float, double 등 및 임의의 등급의 포인터).

내 질문은 : 다양한 컴파일러간에 전체 ABI compatibility을 가정하면 공유 라이브러리와 완전한 API 호환성을 갖기 위해 충족해야하는 유일한 요구 사항입니까?

왜 C++ 라이브러리를 이식 ​​할 수 없습니까? 여기 내 이해가 있습니다 :

사례 1 : 유형 std::string을 고려하십시오. 내부적으로는 char* null로 끝나는 문자열과 크기 정수를 포함합니다. C++ 표준은 이들 중 어느 것이 우선되어야한다고 말하지 않습니다 (맞습니까?). 즉, 함수 인터페이스에 std::string을 입력하면 서로 다른 두 개의 컴파일러가 순서가 다를 수 있으며 작동하지 않습니다.

사례 2 : 가상 메소드가있는 클래스의 상속 및 vtable을 고려하십시오. C++ 표준에는 vtable 포인터가 있어야하는 위치/순서가 필요하지 않습니다 (오른쪽?). 그것들은 다른 변수보다 먼저 클래스의 시작에있을 수 있고, 다른 모든 멤버 변수 뒤에있을 수도 있습니다. 다시 한번이 클래스를 함수에 인터페이스하는 것은 일관성이 없습니다.

첫 번째 질문에 대한 추가 질문 : 함수 호출 중에도 이와 같은 문제가 발생하지 않습니까? 또는 바이너리로 컴파일 된 후에 아무런 문제가 없으며 유형이 더 이상 의미가 없습니까? 예를 들어 C 래퍼 인터페이스에 넣으면 RTTI 요소가 문제를 일으키지 않을까요?

+0

"표준"이란 무엇입니까? 언어 표준은 ABI 보증을 제공하지 않습니다 (거의). 아이테니엄과 같은 ABI 표준은 물론 vtable 등을 포함합니다. 표준 라이브러리 유형 간의 ABI 호환성은 구체적인 구현의 영역이됩니다. –

+0

@BaummitAugen 물론입니다. C++ 표준에는 ABI 보증이 없습니다. 그게 내 질문의 일부 야. 미안 해요, 당신이 진술을하든 진술을하는지 이해하지 못합니다. –

+0

나는 왜 "C++ 라이브러리를 포팅 할 수 없는가?"라는 질문을 이해하려고 노력하고 있습니다. * 언어 표준만을 살펴보면 ABI 호환성을 처음부터 다루지 ​​못하기 때문에 이상한 질문입니다. vtable조차도 구현 세부 사항이므로 종료 할 필요가 없습니다. 구현에서 제공하는 보증을 포함하면 해당 진술은 사실이 아닙니다. x86_64 용 Linux의 사전 빌드 된 패키지와 같은 특정 아키텍처의 C++ 코드에서 이진 파일 (라이브러리 및 실행 파일)을 이식 가능하게 빌드하고 제공 할 수 있습니다. –

답변

4

C++ ABI가없는 이유는 부분적으로 C ABI가 없기 때문입니다. 비얀 스트로브 스트 룹 (source)에서 언급 한 바와 같이 :

기술적 인 어려운 문제는 아마 C++ 바이너리 인터페이스 (ABI)의 부족이다. C ABI도 없지만 대부분의 (모든?) Unix 플랫폼에는 지배적 인 컴파일러가 있고 다른 컴파일러는 호출 규칙 및 구조 레이아웃 규칙을 준수해야합니다. 그렇지 않으면 사용되지 않게됩니다. C++에는 가상 함수 테이블의 레이아웃과 같이 다양 할 수있는 것들이 더 많습니다. 그리고 어떤 공급 업체도이를 따르지 않는 모든 경쟁 업체를 제거하여 C++ ABI를 만들지 않았습니다. 두 개의 서로 다른 PC C 컴파일러의 코드를 서로 연결하는 것이 불가능했던 것과 같은 방식으로, 일반적으로 두 개의 다른 Unix C++ 컴파일러의 코드를 함께 연결할 수 없습니다 (호환성 스위치가없는 한).

ABI가 없기 때문에 컴파일러 구현이 자유로 우며 언어를 여러 유형의 시스템으로 확산 할 수 있습니다.

Windows에서 컴파일러가 결과를 출력하는 방식에 의존하는 일부 플랫폼 종속성이 있습니다. 한 가지 예가 순수 가상 인터페이스가 특정 방식으로 배치되어야하는 COM에서 비롯됩니다. 따라서 Windows에서 대부분의 컴파일러는 동의 할 것입니다.

Windows API는 stdcall 호출 규칙을 사용하므로 Windows API를 코딩 할 때 매개 변수를 함수에 전달하는 방법에 대한 고정 된 규칙 집합이 있습니다. 그러나 다시 이것은 시스템에 따라 다르며 다른 규칙을 사용하는 프로그램을 작성하는 것을 방해하는 요소는 없습니다.

+0

이것은 부분적으로 내용을 명확히합니다. 감사! +1! –

+0

COM은 약간 까다 롭습니다. 순수 가상 인터페이스조차 가지고 있지 않은 C에서 COM을 할 수 있습니다. 그러나 컴파일러에 내장 된 지원이 있으면 COM은 확실히 쉽게 _lot_됩니다. COM 인터페이스가 C++ 순수 가상 인터페이스 인 것으로 가장 할 수 있습니다. – MSalters

관련 문제