C ++ 코드에서 C 함수 호출 ++에서 호출하고 싶은 C 함수가

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


답변