출처 : http://ospace.tistory.com/187
들어가기
C++에서 C에 함수를 사용시 주의해야하는 사항이 있다. 아무 생각없이 C 함수를 사용한다면, 무시무시한 링크오류의 늪에 빠져들고 만다. 늪에 빠져든다고 해도 정신만 차리면 나올 수 있다.
단순히 링크 오류에 대해서만 찾고 계신다면 혹시 아래와 같은 상황이라면 이 글을 읽어보길 바란다.
단순히 링크 오류에 대해서만 찾고 계신다면 혹시 아래와 같은 상황이라면 이 글을 읽어보길 바란다.
- C++ 프로그래밍을 하고 있고 다른 곳에 예제를 그대로 사용하고 있는데 링크에러가 뜬다.
- include나 lib 폴더도 정확하고 불러오는 라이브러리 파일도 정확한데 링크에러가 뜬다.
- 컴파일러 옵션이나 링크 옵션도 이리저리 바꿔보아도 링크에러가 뜬다.
- 다른 함수는 이상이 없는데 특정 일부 함수만 링크에러가 뜬다.
- 지금 사용하는 라이브리가 C용 라이브러리이다.
링크오류
VC++에서는 이런 링크 오류가 LNK2019로 표시된다. 물론 반드시 이렇다는 것은 아니다.
Server.obj : error LNK2019: unresolved external symbol "void __cdecl event_err(int,char const *,...)" (?event_err@@YAXHPBDZZ) referenced in function "void __cdecl on_accept(int,short,void *)" (?on_accept@@YAXHFPAX@Z)
위는 본인이 경험했던 오류이다. 이 문제를 해결하려면 아래 내용을 읽어보길 바란다.
C++에서 C 함수 사용하기
C++에서 검파일된 함수 정의와 C에서 컴파일된 함수 정의는 다르다. 같은 함수 이름을 정의해서 다른 함수로 인식하여 사용하게 된다. 물론 이렇게 하면 나중에 혼란이 발생할 우려가 있으니 사용하면 안되겠지만...
C++에서 C++함수 사용은 당연히 문제가 없다. 그러나 C++에서 C 함수 사용함에 있어서 C 헤더 파일 정의에 주의해야한다.
그럼 C 헤더 파일 정의는 어떻게 될까?
C++에서 C++함수 사용은 당연히 문제가 없다. 그러나 C++에서 C 함수 사용함에 있어서 C 헤더 파일 정의에 주의해야한다.
그럼 C 헤더 파일 정의는 어떻게 될까?
// sample.h
#ifdef __cplusplus
extern "C" {
#endif
void event_err(int eval, const char *fmt, ...);
//... (중략)
#ifdef __cplusplus
};
#endif
#ifdef __cplusplus
extern "C" {
#endif
void event_err(int eval, const char *fmt, ...);
//... (중략)
#ifdef __cplusplus
};
#endif
위와 같이 정이하면 된다. 즉 "__cplusplus"는 C++ 컴파일러를 사용하고 있다는 의미이다.
그래서 C++이라면 extern "C"를 사용해서 선언하면 된다. 간단하게 사용하면,
extern "C" void event_err(int eval, const char *fmt, ...);
처럼 사용할 수 있다. C++과 C를 선택적으로 호환 가능한 헤더 파일을 만들기 위해서 #ifdef 전처리기를 사용해서 선택적으로 선언해서 사용하는 것이 좋다.
추가적인 해결 방안
만약에 기존 소스 코드를 수정해야 하는데, 내가 건드릴 수 없거나, 아니면 수정할 권한을 가지고 있지 않다면 위의 방법과 같이 수정할 수 없다.
그럼 어떻게 할까?
...
방법은 다른 헤더파일을 만들어서 거기서 c헤더 파일을 불러 오고 __cplusplus 전처리기를 추가한다. 예를 들어 "c_api.h"라는 헤더 파일이 있다고 하자. 그러면 "cpp_api.h"파일을 만들어서 아래와 같이 작성한다.
//cpp_api.h file
#ifndef __CPP_API_H__
#define __CPP_API_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <c_api.h> //이부분은 헤더 파일 위치에 따라서 변경될 수 있다.
#ifdef __cplusplus
}
#endif
#endif
생각보다 쉽다. ^^;
결론
링크에러 2019의 실제 에러는 "unresolved external symbol 'symbol' referenced in function 'function'"이다. 즉, 선언한 함수에 대한 실제 구현 부분을 찾을 수 없다는 말이다. 물론 이런 에러가 발생할 경우는 무지 많다.
필자가 위에서 설명한 부분도 그 중에 하나일 뿐이다. 단지 그외의 경우는 이것 저것 하면서 쉽게 찾거나 좀만 하면 해결할 수 있지만, 이 경우는 간단하지만 간과하기 쉬운 부분이다.
C++에서 C 함수를 사용하는 것은 잘 알고 있었던 내용이다. 그러나 링크에러가 발생하고, 단순히 라이브러리 링크에 문제가 있다고, 컴파일러에 문제가 있다고, 아니면 설정에 문제가 있다고만 생각한 것이 큰 실수 였다.
이로 인해 내가 몇시간이라는 귀중한 시간을 소비해버렸다. 정말 짜증이 해일 처럼 밀려온다.
그렇게 해서 혹시 같은 어려움을 갖고 있는 분들에게 도움이 되려고 내용을 작성하였다. 물론 링크 오류외에 C++에서 C함수를 사용하는 내용도 있으나, 그 내용말고 링크 오류에 대한 내용도 같이 참고하면 나중에 도움이 되리라 생각한다.
이로 인해 내가 몇시간이라는 귀중한 시간을 소비해버렸다. 정말 짜증이 해일 처럼 밀려온다.
그렇게 해서 혹시 같은 어려움을 갖고 있는 분들에게 도움이 되려고 내용을 작성하였다. 물론 링크 오류외에 C++에서 C함수를 사용하는 내용도 있으나, 그 내용말고 링크 오류에 대한 내용도 같이 참고하면 나중에 도움이 되리라 생각한다.
헤더 파일로 추가하니까 훨씬 편하네요 !
'Stupid Computer > 2. C 언어' 카테고리의 다른 글
[C/C++] Menu 화면 구성 ! if else if ~ ( 메뉴 10개 이상 넘어갈때 ) (0) | 2014.04.24 |
---|---|
[C/C++] switch case문 10개 이상 만들기 ! (0) | 2014.03.24 |
[json/cjson] json_object_is_type 사용법 (0) | 2014.03.06 |
[C/C++/리눅스/자바] Json 사용법 및 사용예제 (0) | 2014.02.28 |
[C/C++] 기본! 컴파일과 빌드~ 차이점 (0) | 2014.02.28 |
main(int argc, char* argv) 컴파일 옵션 사용 하는 예제 (0) | 2014.02.24 |
윈7에서 비쥬얼 스튜디오 환경변수 설정!!(변수추가) (0) | 2013.06.30 |
[C++] 소셜네트워크서비스 ! SNS 코딩하기, 코딩 프로젝트 예제 ! (3) | 2013.05.29 |
C++ Class개념과 생성자 ! (예제) (0) | 2013.05.18 |
strtok 함수 사용 ! (문자열 토큰단위로 짜르고 배열에 저장) (0) | 2013.05.17 |