101

C++ から呼び出したい C 関数があります。extern "C" void foo()g++ を使用して C 関数をコンパイルできなかったため、" " のようなアプローチを使用できませんでした。しかし、gcc を使用して正常にコンパイルされます。C++ から関数を呼び出す方法はありますか?

4

4 に答える 4

74

他の回答とコメントから少しずつ集めて、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、「いつか別の言語からこれを呼び出すかもしれない」という意味の s はありません。C++ プログラマーがあなたの C 関数を呼び出した場合、それを行う方法は彼らの問題であり、あなたの問題ではありません。また、C++ プログラマーの場合、C ヘッダーは自分のものではない可能性があり、変更しないでください。そのため、マングルされていない関数名 (つまりextern "C") の処理は C++ コードに属します。

extern "C"もちろん、C ヘッダーを宣言にラップする以外は何もしない便利な C++ ヘッダーを自分で作成することもできます。

于 2013-05-31T08:05:07.653 に答える
18

私はファルケン教授の答えに同意しますが、アルネ・メルツのコメントの後に完全な例を挙げたいと思います(最も重要な部分はです#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.hsomecode.c

void foo(void);

でコンパイルするとg++、 then__cplusplus 定義されるため、 に含まれるヘッダーは次のothercode.cppようになります。

extern "C" {

void foo(void);

}
于 2013-05-31T07:30:15.973 に答える