13 Security Lab

[스크랩] extern "C" , name mangling 본문

Computer Science/Programming

[스크랩] extern "C" , name mangling

Maj0r Tom 2013. 2. 14. 11:52

 

 

가끔 일하다보면 extern "C"를 왜 써야 되는지도 모르고
사용하는 신입 코더들을 볼 수 있다. 때론 귀찮게 물어보기도 하고...
나중에 또 물어보면 이 페이지의 주소만 날려주리라. ㅋ

컴파일러는 link 작업시 오브젝트간 함수 이용 및 위치를 파악할 수 있도록,
컴파일시 사용된 함수에 관련된 정보를 오브젝트 파일에 기록하며, 이를 linkage라고 한다.

C++ 컴파일러는 컴파일 과정에서 Name mangling 이란 작업을 한다.
이는 정의되어 있는 함수명을 정해진 규칙에 의해 바꿔버리는 것이다.
(링크 에러날 때 본 적 있는가? 함수명 앞뒤에 붙은 이상한 기호와 숫자들을?)
(그리고 C++ 컴파일러가 왜 바꾸냐고? 그거 설명하려면 두꺼운 책 가져와야 된다... ㅈㅈ
굳이 목적 중에 하나를 설명하자면 override된 함수들의 구별을 위해... 이 정도)

참고로, C는 함수명 앞에 _ (underbar) 하나를 붙인다.

중요한 사실은 "코딩시 함수명과 컴파일 완료된 바이너리 코드에서의 함수명은 다르다" 라는 것이다.
이름을 바꾸는 규칙은 컴파일러에 따라 다르기 때문에 C++ 컴파일러가 다르면 호환이 되지 않는다.
즉, linkage type이 달라져 함수를 찾을 수 없게 되는 것이다.

이는 C++ 컴파일러 간에도 발생하는 문제이며 C와 C++ 컴파일러간에도 발생한다.
(당연하지 않은가, 컴파일러가 다르다니까 ㅋ)

공용의 라이브러리를 제작하였고 이 라이브러리를 사용하는 코더의 계층이 다양하다고 가정해보자.
C 환경에서도 사용을 할 것이고, 다른 C++ 환경에서도 사용할 것이다.
라이브러리 개발&배포자 입장으로써 링크 에러로 아우성치는 유저들 당황스럽다.

이를 피하기 위해 C++ 문법에서는 네임 맹글링을 막기 위해 아래 문장이 제공된다.
즉, C의 네임 형식으로 함수를 컴파일하는 것이다.

extern "C"

따라서 범용적인 라이브러리 헤더라면 아래와 같이 작성되는 것이 좋을 것이다.

// 상략

 

#ifdef __cplusplus

 

extern

 "C" {

#endif



// 중략

 

#ifdef __cplusplus


}

#endif

 

// 하략



자 이제 함수를 C 형식으로 컴파일 했다.
그러면 어떻게 되겠는가? name mangling 회피로 인한 link 문제는 해결이 되었다.

하지만 C 형식이므로 class의 멤버 변수가 될 수도, override가 될 수도 없다.
즉, C++ 고유 특성을 모두 잃어버리게 된다.

 

  http://sweeper.egloos.com/1792976  수까락의 프로그래밍 이야기

 
Comments