'mangling'에 해당되는 글 1건

  1. 2008.12.19 Name Mangling에 대한 고찰
2008. 12. 19. 12:10

Name Mangling에 대한 고찰

Name Mangling에 대한 고찰 Written by Sim-Hyeon, Choe

32비트 컴파일러는 __declspec(dllexport) 지시자를 사용하여 DLL에서 데이터, 함수, 클래스

또는 클래스 멤버 함수를 내보낼 수 있습니다. __declspec(dllexport)는 Object 파일에 익스포트

지시문을 알아서 추가하기 때문에 별도의 모듈 정의파일(.def)를 사용할 필요가 없습니다.

그래서 __declspec(dllexport)를 정의함으로써 컴파일러에게 해당 데이터는 익스포트 될 것임을

알려주게 됩니다. 반대로 익스포트한 모듈의 함수를 사용하기 위해서는 __declspec(dllemport)로

정의하여 알려줘야 합니다.

한가지 예를 들어 보도록 하겠습니다.


MyLibrary.cpp,
MyLibrary.h

2개의 파일이 있다고 가정하겠습니다.

MyLibrary.cpp는 이 모듈의 기능을 정의한 파일입니다.

MyLibrary.h는 이 모듈의 기능에서 필요한 선언부를 담고 있는 헤더 파일입니다.


MyLibrary.h 소스의 선두
----------------------------------------
#ifndef  MYSYSAPI
#define MYSYSAPI __declspec(dllimport)
#endif

MYSYSAPI int __stdcall FuncA(int nA, int nB);
MYSYSAPI int __stdcall FuncB(int nA, int nB);
MYSYSAPI int __stdcall FuncC(int nA, int nB);
----------------------------------------

MyLibrary.cpp 소스의 선두
----------------------------------------
#define   MYSYSAPI __declspec(dllexport)
#include "MyLibrary.h"

int __stdcall FuncA(int nA, int nB)
{
       ... ...
}

int __stdcall FuncB(int nA, int nB)
{
       ... ...
}

int __stdcall FuncC(int nA, int nB)
{
       ... ...
}
----------------------------------------

위의 두 소스를 비교보면 알겠지만, MyLibrary.h는 MyLibrary.cpp와 반대로

__declspec(dllimport)를 사용한다. 소스를 컴파일한 내용으로 해석하면 MyLib

rary.cpp에서는 MYSYSAPI라는 매크로가 전처리하게 되는데, 이어 인클루드한

MyLibrary.h 헤더 파일의 내용을 전처리하는 과정을 따르게 됩니다.

MyLibrary.h 헤더 파일에서 보면, MYSYSAPI라는 매크로가 정의되어 있는지

확인하고 이미 정의되어 있기 때문에 #define MYSYSAPI __declspec(dllimport)

은 건너뛰게 됩니다. 결국 MyLibrary.cpp에서 선언 및 정의된 세 함수가 __declspec

(dllexport)로 사용되어지게 되는데요.

이 라이브러리를 Implicit Linking할 때에도 MyLibrary.h 헤더 파일을 포함해야 합니다.

하지만 여기서의 전처리 흐름은 MYSYS API 매크로가 정의된 적이 없기 때문에

__declspec(dllimport)가 되는 것입니다.

그렇다면 이렇게까지 복잡하게 전처리하고 익스포트 및 임포트하는 이유가 무엇일까요?

일단, 이렇게 정의함으로써 라이브러리를 링킹할 때에는 소스 파일에서 사용시 헤더 파일

에 컴파일러에게 일일이 __declspec(dllimport)으로 알릴 필요가 없게 되어 라이브러리

의 사용자가 더이상 관심을 가지지 않아도 될 것입니다. Win32 API를 사용하듯 필요한

함수만 호출해서 사용하면 되겠지요.

이미 위에서도 설명드렸습니다만, __declspec(dllexport)를 정의하면 별도의 .def 파일

을 생성하여 외부 정의 함수에 대한 정의도 따로 할 필요가 없게 됩니다.

그렇다면 __declspec(dllexport)로 정의한 함수의 심벌명은 어떻게 결정될까요?

Binary Dump로 익스포트 함수의 심벌 정보를 확인하면 다음과 같습니다.

_FuncA01@4
_FuncB02@4
_FuncC03@4



인간이란 망각의 동물이다.

자신의 부단한 노력으로 얻은 소중한 기억이 결국 시간이 지나갈 수록 잊혀

져버린다는 사실에 마음이 아프다.