C++ から呼び出したい C 関数があります。extern "C" void foo()
g++ を使用して C 関数をコンパイルできなかったため、" " のようなアプローチを使用できませんでした。しかし、gcc を使用して正常にコンパイルされます。C++ から関数を呼び出す方法はありますか?
4 に答える
他の回答とコメントから少しずつ集めて、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++ ヘッダーを自分で作成することもできます。
私はファルケン教授の答えに同意しますが、アルネ・メルツのコメントの後に完全な例を挙げたいと思います(最も重要な部分はです#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++
、 then__cplusplus
が定義されるため、 に含まれるヘッダーは次のothercode.cpp
ようになります。
extern "C" {
void foo(void);
}