본문 바로가기

6. With IT/6.3 iOS

extern C문제

출처 : http://blog.naver.com/hermet?Redirect=Log&logNo=87864741


<stdio.h> 와 같이 기존 표준 라이브러리 헤더 파일을 열어보면,

 

 

#ifdef __cplusplus

extern "C" {

#endif

 

 

와 같은 구문을 본 적이 있을 것입니다.

 

딱 보면 예상할 수 있겠지만, c++ 일 경우 이후 구문들은 extern "C" 선언과 함께 스코프로 지정되는 것이겠죠.

 

stdio.h 와 같이 C언어로 작성된 부분들을 c++로 컴파일 할 경우 C 언어 구역임을 명시하는 것입니다.

 

실제로 extern "C" 선언은 필수입니다. 선언하지 않을 시 c언어 함수를 C++ 에서 사용할 경우 링크 시 오류가 발생합니다.

 

//print.c

 

 #include <stdio.h>
 

void print()
{
         printf("Good!\n");
}

 

 

//main.cpp

 

 #include <stdio.h>


void print();

 

void main()
{
        
print();

}

 

 

그리고 컴파일을 해보면( 컴파일은 비주얼 스튜디오 2008 )

 

 

이유는 링크 시, print 함수 심볼을  찾지 못한 것 같습니다. 이는 위에서 언급한 extern "C"로 바로 해결이 됩니다.

 

//main.cpp

 

 #include <stdio.h>


extern "C" void print();

 

void main()
{
      
  print();

}

 

 

print 가 C 함수라고 명시함으로써 해결되는 것은 이해하겠는데 그럼 왜 링킹 실패가 나는 걸까요?

 

C++ 특징 중 오버로드 라는 기능을 알고 있을 겁니다.

 

 

//원 함수

 void print()

{

     //Do Something

}

 

//파라미터 p로 인해 오버로드 된 함수

void print( char* p )

{

    //Do Something...

}

 

 

오버로드 기능으로 두 함수는 기능이 다른 반면 이름은 같습니다. 따라서, C++ 컴파일러는 두 함수를 컴파일 시 구분을 하게 됩니다. 이는 print에 대한 심볼이름을 조금씩 변경하는 것이죠.

 

 

오브젝트 파일로부터 추출한 두 print 함수에 대한 심볼이름입니다. Z5printPc와 Z5printv 라고 확인할 수 있지요.

 

C 같은 경우는 같은 이름의 함수가 존재할 수 없기 때문에 심볼 이름 동일하게 사용되는 반면 C++은 오버로드 기능 때문에 심볼 이름을 바꿔 구분하게 됩니다.

 

따라서 main에서 print 함수를 전방 선언하고 사용할 경우 main은 print에 대한 c++스타일의 심볼이름을 찾게 되고 이로서

c함수로 컴파일한 print 심볼 이름과 엇갈리게 되어 링크 오류가 발생하는 것이죠.

[출처] extern "C"|작성자 Hermet


'6. With IT > 6.3 iOS' 카테고리의 다른 글

AppDelegate에서 ViewController의 Method사용하기  (0) 2014.01.13
Xcode Debug option  (0) 2013.05.28
시너지프로그램 맥10.8 윈도우 7  (0) 2013.04.25
Xcode에서 SVN사용법  (0) 2013.04.25
setter getter??  (0) 2013.03.19