C ++에서 호출하고 싶은 C 함수가 있습니다. extern "C" void foo()
C 함수가 g ++를 사용하여 컴파일되지 않았기 때문에 ” “종류의 접근 방식을 사용할 수 없습니다 . 그러나 gcc를 사용하여 잘 컴파일됩니다. C ++에서 함수를 호출하는 방법에 대한 아이디어가 있습니까?
답변
다음과 같이 C 코드를 컴파일합니다.
gcc -c -o somecode.o somecode.c
그런 다음 다음과 같은 C ++ 코드 :
g++ -c -o othercode.o othercode.cpp
그런 다음 C ++ 링커를 사용하여 함께 연결합니다.
g++ -o yourprogram somecode.o othercode.o
또한 C 함수에 대한 선언을 포함 할 때 C 헤더가 올 것이라고 C ++ 컴파일러에 알려야합니다. 따라서 다음으로 othercode.cpp
시작합니다.
extern "C" {
#include "somecode.h"
}
somecode.h
다음과 같은 내용을 포함해야합니다.
#ifndef SOMECODE_H_
#define SOMECODE_H_
void foo();
#endif
(이 예제에서는 gcc를 사용했지만 원칙은 모든 컴파일러에서 동일합니다. 각각 C와 C ++로 개별적으로 빌드 한 다음 함께 연결합니다.)
답변
명확하게 분리 된 C 및 C ++ 코드로 예제를 제공하기 위해 다른 답변과 주석에서 비트와 조각을 수집하겠습니다.
C 부분 :
foo.h :
#ifndef FOO_H
#define FOO_H
void foo(void);
#endif
foo.c
#include "foo.h"
void foo(void)
{
/* ... */
}
이것을 gcc -c -o foo.o foo.c
.
C ++ 부분 :
bar.cpp
extern "C" {
#include "foo.h" //a C header, so wrap it in extern "C"
}
void bar() {
foo();
}
이것을 컴파일 g++ -c -o bar.o bar.cpp
그런 다음 모두 함께 연결합니다.
g++ -o myfoobar foo.o bar.o
근거 :
C 코드는 일반 C 코드 여야하며 #ifdef
“언젠가 다른 언어에서이 코드를 호출 할 것입니다.”라는 의미가 아닙니다 . 일부 C ++ 프로그래머가 C 함수를 호출하면, 그건 자신의 , 당신이하지 수행하는 방법 문제. 그리고 만약 당신이 C ++ 프로그래머라면, C 헤더는 당신의 것이 아닐 수도 있고 당신은 그것을 변경해서는 안됩니다. 따라서 얽 히지 않은 함수 이름 (예 :)의 처리는 extern "C"
C ++ 코드에 속합니다.
물론 C 헤더를 extern "C"
선언 으로 래핑하는 것 외에는 아무것도하지 않는 편리한 C ++ 헤더를 직접 작성할 수도 있습니다 .
답변
나는 Prof. Falken의 대답에 동의 하지만 Arne Mertz의 의견에 따라 완전한 예를 들었습니다 (가장 중요한 부분은 #ifdef __cplusplus
).
somecode.h
#ifndef H_SOMECODE
#define H_SOMECODE
#ifdef __cplusplus
extern "C" {
#endif
void foo(void);
#ifdef __cplusplus
}
#endif
#endif /* H_SOMECODE */
somecode.c
#include "somecode.h"
void foo(void)
{
/* ... */
}
othercode.hpp
#ifndef HPP_OTHERCODE
#define HPP_OTHERCODE
void bar();
#endif /* HPP_OTHERCODE */
othercode.cpp
#include "othercode.hpp"
#include "somecode.h"
void bar()
{
foo(); // call C function
// ...
}
그런 다음 Falken 교수의 지시에 따라 컴파일하고 연결합니다.
로 컴파일 할 때 gcc
매크로 __cplusplus
가 정의되지 않았으므로에 somecode.h
포함 된 헤더 somecode.c
는 전처리 후 다음 과 같기 때문에 작동합니다 .
void foo(void);
컴파일 할 때 g++
, 다음 __cplusplus
되고 정의하고,에 포함 된 헤더 때문에 othercode.cpp
지금과 같다 :
extern "C" {
void foo(void);
}
답변
이 답변은 Arne의 근거가 올바른 경우에서 영감을 얻었습니다. 한 공급 업체가 한때 C와 C ++를 모두 지원하는 라이브러리를 작성했습니다. 그러나 최신 버전은 C 만 지원했습니다. 코드에 남겨진 다음 흔적 지시문은 오해의 소지가 있습니다.
#ifdef __cplusplus
extern "C" {
#endif
이로 인해 C ++로 컴파일하는 데 몇 시간이 소요되었습니다. 단순히 C ++에서 C를 호출하는 것이 훨씬 쉬웠습니다.
ifdef __cplusplus 규칙은 단일 책임 원칙을 위반합니다. 이 규칙을 사용하는 코드는 한 번에 두 가지 작업을 수행하려고합니다.
- (1) C에서 함수 실행-및-
- (2) C ++에서 동일한 기능 실행
미국식 영어와 영국식 영어를 동시에 쓰려고하는 것과 같습니다. 이것은 불필요하게 #ifdef __thequeensenglish 스패너 #elif __yankeeenglish 렌치 #else 코드를 코드로 읽기 어렵게 만드는 쓸모없는 도구입니다.
간단한 코드와 작은 라이브러리의 경우 ifdef __cplusplus 규칙이 작동 할 수 있습니다. 그러나 복잡한 라이브러리의 경우 한 언어 또는 다른 언어를 선택하고 그대로 유지하는 것이 가장 좋습니다. 언어 중 하나를 지원하는 것은 둘 다 지원하는 것보다 유지 관리가 덜 필요합니다.
이것은 Ubuntu Linux에서 컴파일하기 위해 Arne의 코드를 수정 한 기록입니다.
foo.h :
#ifndef FOO_H
#define FOO_H
void foo(void);
#endif
foo.c
#include "foo.h"
#include <stdio.h>
void foo(void)
{
// modified to verify the code was called
printf("This Hello World was called in C++ and written in C\n");
}
bar.cpp
extern "C" {
#include "foo.h" //a C header, so wrap it in extern "C"
}
int main() {
foo();
return(0);
}
Makefile
# -*- MakeFile -*-
# dont forget to use tabs, not spaces for indents
# to use simple copy this file in the same directory and type 'make'
myfoobar: bar.o foo.o
g++ -o myfoobar foo.o bar.o
bar.o: bar.cpp
g++ -c -o bar.o bar.cpp
foo.o: foo.c
gcc -c -o foo.o foo.c