2011-12-24 2 views
1

내가 그게 내가 필요한 모든을했지만 컴파일러가 불평을 기대하고 C 헤더 파일의 포함과 함께 C++ 헤더 라인 extern "C" void perlinTest(void);을 추가 :이 라이브러리가 아닌 경우iPhone의 C++ 코드에서 C 함수를 어떻게 호출합니까?

Undefined symbols for architecture i386: 
    "perlinTest()", referenced from: 
     CreateRenderer3(IResourceManager*) in Renderer.o 
+1

또한 해당 기능을 제공하는 라이브러리와 링크해야합니다. – Mat

+0

이것은 도서관이 아닙니다. 나는 c 함수와 그것을 호출하는 C++ 코드를 작성했다. – Xavier

+0

그런 다음 C 코드가 컴파일되고 C++ 코드와 링크되어 있는지 확인해야합니다. – Mat

답변

1

C++ 코드는 함수가 C 함수임을 알고 있어야합니다. 상황에 맞는 현실적인 예는 것

extern "C" [prototype]; 

: 이렇게하려면, 당신은 이런 식으로 선언 할 필요가

extern "C" void perlinTest(); 

그 이유는 C++ function names are mangled 그의 유형에 대해 알려줍니다 뭔가있다 매개 변수 가장 낮은 레벨에서는 오버로드가 허용됩니다. 즉, 같은 이름을 가진 두 개의 표시 가능한 심볼을 가지는 것이 합법적 인 것은 아니므로 C++은 함수 이름에 매개 변수의 유형을 나타내는 마커를 포함함으로써 해당 심볼을 허용합니다. 예를 들어 void perlinTest()은 내 라이온 상자에 g++ (아마도 clang++)으로 _Z10perlinTestv으로 맹 글링되어 있지만 ABI와 관련이 있으며 다른 플랫폼에서는 동일하지 않습니다.

그러나 C는 오버로드를 지원하지 않으며 함수는 이름 맹 글링의 영향을받지 않으므로 C++ 코드가 전화를 걸려고 할 때 맹 글링 된 이름을 사용해서는 안된다는 것을 알아야합니다. 이것은 extern "C"이 컴파일러에게 알려주는 것입니다. 헤더 파일은 C와 C++에서 읽을 수해야하는 경우

, 일반적인 관행은 extern "C" 블록 (extern "C" { /* declarations */ }) 자체가 #ifdef __cplusplus 처리기 지시문에 싸여 (그래서 C 코드가 extern "C"이 표시되지 않는 그들을 래핑하는 것입니다 암호).

#ifdef __cplusplus 
extern "C" { 
#endif 

/* header body */ 

#ifdef __cplusplus 
} 
#endif 
0

, 당신은 어떤 필요하지 않습니다 extern C. .c 파일 확장자로 바꾸고 컴파일러가이를 인식하도록 구성하는 방법 (.c 코드가 아닌 것처럼 보임)

0

실제로 void perlinTest(void)을 구현 했습니까?

처음에는 함수를 실제로 구현하지 않고 단순히 선언 할 수있을 것입니다. 다른 클래스/객체가 실제로 perlinTest()을 호출하지 않으면 Xcode는 기꺼이 앱을 빌드하고 실행하며 오류는 발생하지 않습니다. 은 실제로 아무 데서도 참조되지 않으므로 함수가 실제로 구현되지 않았는지 상관하지 않습니다.

다른 클래스 중 하나 (예 : CreateRenderer3(IResourceManager*) in Renderer.o)에서 perlinTest()을 호출하면 링커는 심볼을 해석 할 수 있는지 확인하고 실제로 베어 본 정의를 구현하지 않은 경우 (아래 참조), 당신은 당신이 가진 것과 같은 오류를 범할 가능성이 높습니다.

, 연결 오류 방지해야 다음과 같은 최소한의 구현 :이 디버깅하는 데 사용할 수있는

void perlinTest(void) { 

} 
+0

예 구현했습니다. – Xavier

0

한 트릭은 당신의 perlinTest() 기능에 의도적 인 오류를 소개하는 것입니다. 그런 다음 앱을 빌드하고 컴파일러에서 오류를보고하는지 확인하십시오. 어쨌든 응용 프로그램이 컴파일되면 문제는이 기능이있는 파일이 빌드중인 대상의 일부가 아니라는 것입니다.

붙여 넣기 한 오류는 i386 아키텍처에서 발생하므로 iPhone 일 수 없습니다. 아마도 아이폰 시뮬레이터를 대신 구축하고있을 것이다.

편집 : 다음 단계는 Xcode에서 발행 한 링크 명령에 C 함수가있는 .o가 포함되어 있는지 확인하는 것입니다. 그렇다면 .o 파일의 내용을 nm 유틸리티로 덤프하여 .o 파일에서 함수 이름이 어떻게 보이는지 확인해야합니다.

+0

오류가 발생하면 perlinTest가 포함 된 파일이 컴파일되지 않았습니다. – Xavier

+0

예 iPhone 시뮬레이터 용으로 컴파일하고 있습니다. – Xavier

관련 문제