programing

C++ 코드에서 C 함수를 호출합니다.

goodsources 2022. 7. 10. 21:23
반응형

C++ 코드에서 C 함수를 호출합니다.

C++에서 호출하고 싶은 C 기능이 있습니다."를 사용할 수 없었습니다.extern "C" void foo()" G++를 사용하여 C 함수를 컴파일하지 못했기 때문에 일종의 접근법입니다.하지만 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 헤더는 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 

#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++ 헤더를 직접 쓸 수도 있습니다.이 헤더는 C 헤더를 랩하는 것 이외에는 아무것도 하지 않습니다.extern "C"선언.

이 답변은 Arne의 논거가 옳았던 사례에서 영감을 얻었다.한 벤더가 한때 C와 C++를 모두 지원했던 라이브러리를 작성했지만 최신 버전은 C만 지원했습니다.코드에 남겨진 다음과 같은 잔존 지시는 오해를 불러일으켰다.

#ifdef __cplusplus
extern "C" {
#endif

이것을 C++로 컴파일 하는 데 몇 시간이 걸렸습니다.단순히 C++에서 C를 호출하는 것이 훨씬 쉬웠습니다.

ifdef __cplus plus 규칙이 단일 책임 원칙에 위배됩니다.이 규칙을 사용하는 코드는 다음 두 가지 작업을 동시에 수행하려고 합니다.

  • (1) C의 함수를 실행한다.
  • (2) C++에서 동일한 기능을 실행한다.

그것은 미국어와 영국어를 동시에 쓰려고 하는 것과 같다.이것은 불필요하게 #ifdef __thequenglish spanner #elif __yankeeenglish wrench #else를 쓸모없는 도구로 만들고 #endif 코드를 읽기 어렵게 만듭니다.

단순한 코드와 작은 라이브러리의 경우 ifdef __cplus 규칙이 적용될 수 있지만 복잡한 라이브러리의 경우 언어 중 하나를 선택하여 그대로 사용하는 것이 가장 좋습니다.어느쪽인가를 서포트하는 경우는, 양쪽 모두를 서포트하는 경우보다 유지보수가 적게 됩니다.

이것은 Ubuntu Linux에서 컴파일하기 위해 Anne의 코드를 수정한 기록입니다.

foo.h:

#ifndef FOO_H
#define FOO_H

void foo(void);

#endif 

#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 -*-
# 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

교수님 말씀에 동의합니다. 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)
{
    /* ... */
}

other code.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.hincluded included에 .somecode.c전처리 후 다음과 같습니다.

void foo(void);

할 때 ''로 컴파일 할 때''g++ , , , 「 」__cplusplus 정의되어 있기 때문에 헤더는othercode.cpp지금은 그렇다.

extern "C" {

void foo(void);

}

언급URL : https://stackoverflow.com/questions/16850992/call-a-c-function-from-c-code

반응형