프로그래밍/C,C++,C#

[C++/C] C++에서 C파일 호출하여 컴파일(LNK2001, LNK1120 오류) feat. 맹글링(Mangling)

Beginner:) 2022. 5. 5.
320x100

C++에서 C파일을 호출하여 컴파일하면 아래와 같은 에러가 발생하는데 테스트해본다.

오류	LNK2001	확인할 수 없는 외부 기호 "int __cdecl testFunctionC(void)" (?testFunctionC@@YAHXZ)
오류	LNK1120	1개의 확인할 수 없는 외부 참조입니다.

 

 

먼저 C++ 프로젝트를 생성하여 main.cpp, func.h, func.c를 생성한다.

 

 

생성한 

 

 

- main.cpp

#include"func.h"
#include <iostream>

int main(void){
	std::cout << testFunctionC() << std::endl;
	return 0;
}

 

- func.h

int testFunctionC();

 

- func.c

#include"func.h"

int testFunctionC() {
	return 1;
}

 

실행하면 다음과 같은 에러가 발생한다.

 

이러한 이유가 나타나는 이유는 당연히 C++과 C는 다르기 때문,

 

더 깊게보자면 C언어는 함수이름 자체가 고유한 ID이다. 따라서 오버로딩(Overloading)이 불가능

 

C++에서 객체지향 개념이 도입되면서 오버로딩이 생겼는데 

 

말했다싶이 함수이름은 고유ID이기 때문에 오버로딩이 생기면 ID가 고유하지 않는 문제가 존재하게되어 이 함수의 고유 이름을 조금씩 변형시킨다. (컴파일러마다 변형 규칙은 다르다)

 

이를 맹글링(Mangling) 또는 네임 데코레이션(Name Decoration)이라 함.

 

 

그래서 결론은  C언어에서는 맹글링이란 개념이 없기때문에 함수이름이 고유의 ID인데

 

C++에서는 include된 C의 함수를 찾을때 맹글링 된 이름으로 찾기때문에

 

확인할 수 없는 외부 기호(NK(2001) + 확인할 수 없는 외부 참조(NK1120) 오류를 뱉음

 

그래서 C++에서 C를 호출하려면 맹글링을 하지 않고 ID를 찾아야한다.

 

 

extern "C"{ }를 사용할 수 있다.

 

- func.h

#ifdef __cplusplus
extern "C" {
#endif
	int testFunctionC();

#ifdef __cplusplus
}
#endif

#ifdef ~ #endif 는 전처리기 조건부 컴파일, 

__cplusplus는 컴파일하는 언어가 C++인지 확인하는 전처리기 매크로이다

 

 

 

https://stackoverflow.com/questions/1041866/what-is-the-effect-of-extern-c-in-c

반응형

댓글