C++ 네임스페이스 안에 외부 "C" 링크가 있습니까?
namespace someNameSpace {
extern "C" void doSomething()
{
someOperations();
}
}
뛰고싶습니다doSomething()
C++ 및 C 환경 모두에서 사용할 수 있습니다.
이스someNameSpace
여전히 캡슐화 중인doSomething()
그것을 들춰보면extern "C"
연계?
C++ 쪽의 글로벌 네임스페이스를 오염시키지 않으면서 C++와 C 사이에 기능을 공유할 수 있는 좋은 방법이 있습니까?
편집: 이 코드는 주로 C++ 모드에서 사용되지만 C 링크는 테스트용으로만 사용되기 때문에 이것이 더 좋은 방법이라고 생각합니다.
namespace someNameSpace {
#ifdef COMPILE_FOR_C_LINKAGE
extern "C"
#else
extern "C++"
#endif
{
void doSomething()
{
someOperations();
}
}
}
당신의 코드는 작동하지만 당신은 모든 기능이extern "C"
링크는 이름의 같은 공간을 공유하지만, 이는 "이름 공간"의 C++ 개념과 혼동되지 않습니다.당신의 기능은 정말.someNameSpace::doSomething
, 하지만 당신은 다른 것을 가질 수 없습니다.extern "C"
이름을 지정하지 않은 함수doSomething
다른 네임스페이스에도 적용할 수 있습니다.
7.5/6 참조:
특정 이름을 가진 최대 하나의 함수는 C 언어 연결을 가질 수 있습니다.서로 다른 네임스페이스 범위에 나타나는 동일한 함수 이름(자격을 부여하는 네임스페이스 이름 무시)을 가진 C 언어 링크가 있는 함수에 대한 두 개의 선언은 동일한 함수를 참조합니다.서로 다른 네임스페이스 범위에 나타나는 이름이 같은 C 언어 연결을 가진 변수(자격을 부여하는 네임스페이스 이름 무시)에 대한 두 가지 선언에서 동일한 변수를 참조합니다.C 언어 연결을 가진 개체는 두 선언이 동일한 개체를 나타내는 경우가 아니라면 전역 범위의 변수와 동일한 이름으로 선언되어서는 안 됩니다. 선언이 다른 번역 단위로 나타나는 경우 진단이 필요하지 않습니다.C 언어 연결이 있는 변수는 C 언어 연결이 있는 함수와 동일한 이름으로 선언되어서는 안 되며(각 이름에 적합한 네임스페이스 이름은 무시), 선언이 다른 번역 단위로 나타나는 경우 진단이 필요하지 않습니다.[참고:C 언어 연결이 있는 지정된 이름을 가진 엔티티에 대한 정의는 프로그램에 하나만 표시될 수 있습니다(3.2 참조). 이는 해당 엔티티가 둘 이상의 네임스페이스 범위에 정의되어서는 안 된다는 것을 의미합니다.— 끝음]
귀사나 프로젝트의 글로벌 스타일 중재자가 코드 기반에 적합한 이름 지정 정책에 대해 조언해 줄 수 있어야 합니다.
Kerrek SB 답변에 명시된 행동을 설명하기 위한 코드 조각입니다.
#include <iostream>
namespace C{
void Hello(){
std::cout<<"Hello"<<std::endl;
}
extern "C" void HelloThere(){
std::cout<<"Hello There from extern \"C\""<<std::endl;
}
}
extern "C" void HelloThere();
int main() {
C::Hello();
C::HelloThere(); //Compiles
//Hello(); <--- does not compile
HelloThere(); //Also compiles and prints the same as C::HelloThere() !!!
return 0;
}
http://ideone.com/X26wfR 에서 라이브로 만나보세요.
C++ ABI에서는 네임스페이스를 망글링해야 합니다.그래서 이것은:
namespace foo
{
void bar(int){}
}
는 이러한 기호로 다소 번역됩니다.
foo::bar(int)
컴파일러가 비슷한 기호인 CABI를 사용하도록 강요할 때
namespace foo
{
extern "C" void bazz(int){}
}
컴파일 후 다음과 같이 나타납니다.
bazz
godbolt: https://godbolt.org/z/BmVpSQ 에서 차이를 확인할 수 있습니다.
CABI에는 함수와 함께 망치는 네임스페이스나 인수 목록이 없으므로 전체 코드에서 이러한 기호를 1개만 가질 수 있습니다.두 번 정의:
namespace foo
{
extern "C" void bazz(int){}
}
namespace foo2
{
extern "C" void bazz(int){}
}
int main()
{
foo2::bazz(5);
return 0;
}
불법입니다클랑 컴파일러는 다음과 같은 경우 단순한 컴파일 오류를 발생시킵니다.
https://wandbox.org/permlink/r5CUXm7OKePtG35L
gcc 컴파일러도 오류를 발생시키지만 훨씬 더 신비로워 보입니다.
https://wandbox.org/permlink/BiN0auna9klBg5GE
언급URL : https://stackoverflow.com/questions/28996944/extern-c-linkage-inside-c-namespace
'source' 카테고리의 다른 글
반복 합계에 우커머스 구독 사용자 지정 수수료 추가 (0) | 2023.10.14 |
---|---|
운영 중인 도커 컨테이너의 확장 방법 (0) | 2023.10.14 |
다트의 AngularJS 스타일 프로그래밍? (0) | 2023.10.14 |
node.js에서 ID로 사용할 랜덤 SHA1 해시를 생성하는 방법? (0) | 2023.10.14 |
끝에 새 줄 문자를 붙이지 않고 pl/sql을 사용하여 문자열을 인쇄하는 방법 (0) | 2023.10.14 |