문제

나는 프로그래밍 언어 과정을 수강하고 있으며 우리는 extern "C" 선언.

이 선언은 "IT 인터페이스 C 및 C ++"이외의 더 깊은 수준에서 어떻게 작동합니까? 이것이 프로그램에서 발생하는 바인딩에 어떤 영향을 미칩니 까?

도움이 되었습니까?

해결책

extern "C" 다음 기호가 엉망이되었습니다 (훌륭하게 꾸민).


예시:

파일에 다음 코드가 있다고 가정 해 봅시다. test.cpp:

extern "C" {
  int foo() {
    return 1;
  }
}

int bar() {
  return 1;
}

당신이 달리면 gcc -c test.cpp -o test.o

기호 이름을 살펴보십시오.

00000010 T _Z3BARV

00000000 T Foo

foo() 이름을 유지합니다.

다른 팁

C와 C ++에서 컴파일 할 수있는 일반적인 기능을 살펴 보겠습니다.

int Add (int a, int b)
{
    return a+b;
}

이제 C에서는 함수를 내부 "_add"라고합니다. 반면 C ++ 함수는 Name-Mangling이라는 시스템을 사용하여 내부적으로 완전히 다른 것으로 호출됩니다. 기본적으로 매개 변수의 동일한 함수가 다른 내부 이름을 갖도록 함수의 이름을 지정하는 방법입니다.

따라서 add ()가 add.c에 정의되고 Add.h에 프로토 타입이있는 경우 Add.h를 C ++ 파일에 포함 시키려고하면 문제가 발생합니다. C ++ 코드는 add.c의 이름과 다른 이름의 함수를 찾고 있으므로 링커 오류가 발생합니다. 이 문제를 해결하려면이 방법으로 Add.c를 포함시켜야합니다.

extern "C"
{
#include "add.h"
}

이제 C ++ 코드는 C ++ 이름 Mangled 버전 대신 _add와 연결됩니다.

그것은 표현의 사용 중 하나입니다. 결론, C ++ 프로그램에서 엄격하게 C 인 코드를 컴파일 해야하는 경우 (포함 명령문 또는 다른 수단을 통해) 외부 "C"{...} 선언으로 래핑해야합니다.

extern "c"로 코드 블록을 표시하면 시스템에 C 스타일 연결을 사용하도록 지시합니다.

이것은 주로 링커가 이름을 관리하는 방식에 영향을 미칩니다. C ++ 스타일 이름 Mangling (운영자 오버로드를 지원하기에 더 복잡한)을 사용하는 대신 링커에서 표준 C 스타일 이름 지정을 얻습니다.

C ++에서 함수의 이름/기호는 실제로 다른 클래스/네임 스페이스가 동일한 서명의 함수를 가질 수 있도록 다른 것으로 바뀌 었습니다. C에서는 기능이 모두 전 세계적으로 정의되며 그러한 맞춤형 변경 프로세스가 필요하지 않습니다.

C ++ 및 C를 서로 대화하게하려면 "Extern C"는 컴파일러에게 C 컨벤션을 사용하지 않도록 지시합니다.

그것은 주목해야합니다 extern "C" 또한 함수 유형을 수정합니다. 낮은 레벨에서 사물을 수정할뿐만 아니라 다음과 같습니다.

extern "C" typedef void (*function_ptr_t)();

void foo();

int main() { function_ptr_t fptr = &foo; } // error!

유형 &foo TypEdef가 지정된 유형과 같지 않습니다 (코드는 일부 컴파일러는 아니지만 일부는 코드가 허용되지만).

Extern C는 C ++ 컴파일러에 의한 이름 Mangling에 영향을 미칩니다. C ++ 컴파일러가 이름을 맹글하지 않도록하거나 C 컴파일러와 같은 방식으로 담그는 방법입니다. 이것이 C 및 C ++를 인터페이스하는 방식입니다.

예로서:

extern "C" void foo(int i);

기능을 C 모듈에서 구현할 수 있지만 C ++ 모듈에서 호출 할 수 있습니다.

C ++ 모듈에 정의 된 C ++ 함수 (C ++ 클래스를 사용할 수 없음)를 호출하기 위해 C 모듈을 가져 오려고 할 때 문제가 발생합니다. C 컴파일러는 마음에 들지 않습니다 extern "C".

따라서 이것을 사용해야합니다.

#ifdef __cplusplus
extern "C" {
#endif

void foo(int i);

#ifdef __cplusplus
}
#endif

이제 헤더 파일에 나타나면 C 및 C ++ 컴파일러 모두 선언에 만족하며 이제 C 또는 C ++ 모듈로 정의 될 수 있으며 C 및 C ++ 코드 모두에서 호출 할 수 있습니다.

Extern "C"는 동봉 된 코드가 C 스타일 링크와 이름 Mangling을 사용한다는 것을 나타냅니다. C ++는 더 복잡한 이름 Mangling 형식을 사용합니다. 예는 다음과 같습니다.

http://en.wikipedia.org/wiki/name_mangling

int example(int alpha, char beta);

C : _example

C ++에서 : __Z7exampleic

업데이트 : gmannickg가 주석에서 언급 한대로 이름 Mangling의 패턴은 컴파일러 의존적입니다.

외부 "C"는 C 컴파일러와 C ++ 컴파일러가 객체 파일에서 다른 형식으로 소스를 변환하기 때문에 C 바인딩이있는 함수를 선언하는 키워드입니다.

예를 들어, 코드 스 니펫은 다음과 같습니다.

int _cdecl func1(void) {return 0}
int _stdcall func2(int) {return 0}
int _fastcall func3(void) {return 1}

32 비트 C 컴파일러는 다음과 같이 양식으로 코드를 변환합니다.

_func1
_func2@4
@func3@4

CDECL에서 func1은 '로 번역됩니다._이름'

stdcall에서 func2는 '로 번역됩니다._name@x'

FastCall에서 FUNC2는 '로 번역됩니다.@name@x'

'엑스'매개 변수 목록의 매개 변수의 바이트 수를 의미합니다.

Windows에 대한 64 비트 협약에는 주요 밑줄이 없습니다

C ++에서 클래스, 템플릿, 네임 스페이스 및 연산자 과부하가 소개됩니다. 동일한 이름의 두 기능이 허용되지 않으므로 C ++ 컴파일러는 기호 이름의 유형 정보를 제공합니다.

예를 들어, 코드 스 니펫은 다음과 같습니다.

int func(void) {return 1;}
int func(int) {return 0;}
int func_call(void) {int m=func(), n=func(0);}

C ++ 컴파일러는 코드를 다음과 같이 변환합니다.

int func_v(void) {return 1;}
int func_i(int) {return 0;}
int func_call(void) {int m=_func_v(), n=_func_i(0);}

'_v'와 '_i'는 'void'및 'int'의 유형 정보입니다.

다음은 MSDN의 인용문입니다

"외부 키워드는 변수 또는 함수를 선언하고 외부 링키지가 있음을 지정합니다 (이름은 정의 된 것 이외의 파일에서 표시됩니다). 변수를 수정할 때 외부는 변수가 정적 지속 시간을 갖도록 지정합니다 (할당됩니다. 프로그램이 종료 될 때 프로그램이 시작되고 거래 될 때) 변수 또는 함수는 다른 소스 파일 또는 동일한 파일에서 정의 될 수 있습니다. 파일 범위에서 변수 및 함수의 선언은 기본적으로 외부입니다. "

http://msdn.microsoft.com/en-us/library/0603949d%28vs.80%29.aspx

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