카테고리 없음

extern C 오버로딩 지원 컴파일러와의 호환

시코. 2024. 2. 7. 10:32
728x90

https://rootfriend.tistory.com/entry/extern-C

 

extern "C"

C뿐만 아니라 모든 프로그래밍 언어는 목적 파일(obj)을 만들고 링크에 의해 목적 파일을 연결함으로써 최종 실행 파일을 만든다. 이때 목적 파일로 자신이 정의한 함수의 명칭과 주소를 공개하

rootfriend.tistory.com

 

모든 언어는 목적파일(obj)를 만들고 링크에 의해 최종 실행파일을 만든다.

목적파일엔 정의한 함수의 명칭과 주소가 공개됨.

이것은 표준 포멧이 규정되어 있어 다른 언어로 컴파일된 파일들이 링크가 가능.

범용링커는 함수 이름으로만 찾아 오버로딩된 함수를 구분 못함.

c++은 이런 부분의 지원을 위해 오버로딩된 함수에 추가적으로 문자들( 이상한 기호 )을 포함시킴.

이를 이름 장식(name mangling)이라고 함.

?Add@@YANNN@Z

?Add@@YAHHHH@Z

?Add@@YAHHH@Z

 

하지만 다른언어에서는 여전히 찾지 못할 수 있다.

이때 사용하는 지시자가 extern "C"다.

오버로딩 기능을 금지한다.

범용 함수가 만들어진다.

C에서도 함수가 호출 가능하다.

차후에 윈도우즈 환경에서 DLL을 만들때에 이 지시자를 필요로한다.

DLL포맷도 이름으로 함수를 찾기 때문에 오버로딩을 지원하지 않는다.

 

extern "C" 지시자는 다른언어를 위해 이름장식을 사용하지 않게 해주지만

이미 C로 만들어진 함수를 C++에서 호출하고자 할때도 이 지시자가 필요하다.

C++링커는 기본적으로 이름장식이 있는 이름을 찾기때문에 C에서 작성된 이름장식이 없는 함수를 찾지 못하기 때문이다.

 

WINAPI의 의미(__stdcall)

function calling에 있어 여러 convention이 있기 마련이다.

언어별로 다 다르기 때문

어떤 dll을 만들었을때 여러 언어에서 사용하려면 그 언어용으로 따로 만들어야한다.

dll의 본래 취지를 벗어남. 효율적이지 못함.

이때 WINAPI라는 선언을 한다.

#define WINAPI __stdcall

라고 되어있다.

__stdcall은 선언된 함수가 return되기 전에 stack을 정리한다.

비교대상인 __cdecl은 함수가 return된 이후에 stack을 정리하게 된다.(c/c++)

__cdecl은 stack을 정리하는 코드가 필요하게 된다.

CALLBACK macro나 PASCAL macro도 찾아보면 __stdcall이다.

(문자 그대로 standard calling)

이외에도 차이가 있겠지만 용도는 서로다른 binary에 공통된 interface를 제공하기 위한 목적이 있다.

- 네이버에서 greathjm 님의 글을 발췌했습니다.

출처: https://rootfriend.tistory.com/entry/extern-C [A Kind of Magic:티스토리]

 

이외에 직접 컴파일 해보는 코드들은 아래에서..

 

extern "C"

C뿐만 아니라 모든 프로그래밍 언어는 목적 파일(obj)을 만들고 링크에 의해 목적 파일을 연결함으로써 최종 실행 파일을 만든다. 이때 목적 파일로 자신이 정의한 함수의 명칭과 주소를 공개하

rootfriend.tistory.com

https://blog.naver.com/work1989/221275066623

 

728x90