私は次のようにします:
(MSVC を使用している場合は、GCC コンパイル コマンドを無視してください)
ファイルaaa.h、aaa.cppで定義されたAAAという名前の C++ クラスがあり、クラスAAAには、 C コードで有効にしたいsayHi(const char *name)という名前のメソッドがあるとします。
クラスAAAの C++ コード- 純粋な C++、私はそれを変更しません。
aaa.h
#ifndef AAA_H
#define AAA_H
class AAA {
public:
AAA();
void sayHi(const char *name);
};
#endif
aaa.cpp
#include <iostream>
#include "aaa.h"
AAA::AAA() {
}
void AAA::sayHi(const char *name) {
std::cout << "Hi " << name << std::endl;
}
C++ に対して通常行われるように、このクラスをコンパイルします。このコードは、C コードで使用されることを「知りません」。次のコマンドを使用します。
g++ -fpic -shared aaa.cpp -o libaaa.so
ここで、同じく C++ で C コネクタを作成します。
ファイルaaa_c_connector.h、aaa_c_connector.cppで定義します。このコネクタは、 AAAのインスタンスを使用し、そのメソッドを呼び出すAAA_sayHi(cosnt char *name)という名前の C 関数を定義します。
aaa_c_connector.h
#ifndef AAA_C_CONNECTOR_H
#define AAA_C_CONNECTOR_H
#ifdef __cplusplus
extern "C" {
#endif
void AAA_sayHi(const char *name);
#ifdef __cplusplus
}
#endif
#endif
aaa_c_connector.cpp
#include <cstdlib>
#include "aaa_c_connector.h"
#include "aaa.h"
#ifdef __cplusplus
extern "C" {
#endif
// Inside this "extern C" block, I can implement functions in C++, which will externally
// appear as C functions (which means that the function IDs will be their names, unlike
// the regular C++ behavior, which allows defining multiple functions with the same name
// (overloading) and hence uses function signature hashing to enforce unique IDs),
static AAA *AAA_instance = NULL;
void lazyAAA() {
if (AAA_instance == NULL) {
AAA_instance = new AAA();
}
}
void AAA_sayHi(const char *name) {
lazyAAA();
AAA_instance->sayHi(name);
}
#ifdef __cplusplus
}
#endif
再度、通常の C++ コンパイル コマンドを使用してコンパイルします。
g++ -fpic -shared aaa_c_connector.cpp -L. -laaa -o libaaa_c_connector.so
これで、C 関数AAA_sayHi(const char *name)を実装する共有ライブラリ (libaaa_c_connector.so) ができました。これで、C のメイン ファイルを作成し、まとめてコンパイルできます。
main.c
#include "aaa_c_connector.h"
int main() {
AAA_sayHi("David");
AAA_sayHi("James");
return 0;
}
C コンパイル コマンドを使用してコンパイルします。
gcc main.c -L. -laaa_c_connector -o c_aaa
$PWD を含むように LD_LIBRARY_PATH を設定する必要があります。実行可能ファイル./c_aaaを実行すると、期待どおりの出力が得られます。
Hi David
Hi James
編集:
一部の Linux ディストリビューションで-laaa
は-lstdc++
、最後のコンパイル コマンドにも必要になる場合があります。@AlaaM に感謝します。注意のために