1. ホーム
  2. c++

[解決済み] C言語からC++の関数を呼び出すには?

2023-01-22 20:55:59

質問

これは知っています。

C++からCの関数を呼び出す。

もし私のアプリケーションがC++で、Cで書かれたライブラリから関数を呼び出す必要があったとしたら、私は次のように使うでしょう。

//main.cpp

extern "C" void C_library_function(int x, int y);//prototype
C_library_function(2,4);// directly using it.

これなら、名前を混乱させることなく C_library_function となり、リンカは入力の *.lib ファイルに同じ名前を見つけるので、問題は解決します。

C++の関数をCから呼び出す?

しかし、ここで私はCで書かれた大規模なアプリケーションを拡張しており、C++で書かれたライブラリを使用する必要があります。C++の名前のマングリングは、ここで問題を引き起こしています。リンカーは未解決のシンボルについて文句を言っています。C++コンパイラは、他の多くのものを破壊してしまうので、私のCプロジェクトに使用することはできません。どのような解決策があるのでしょうか?

ところで、私は MSVC を使用しています。

どのように解決するのですか?

C++ コードの機能を公開するための C API を作成する必要があります。基本的には、extern "C" と宣言された C++ コードで、C++ ライブラリをラップする純粋な C API (たとえば、クラスを使用しない) を記述する必要があります。そして、作成した純粋な C ラッパー ライブラリを使用します。

C API は、C がオブジェクト指向でないにもかかわらず、オプションでオブジェクト指向のスタイルに従うことができます。例

 // *.h file
 // ...
 #ifdef __cplusplus
 #define EXTERNC extern "C"
 #else
 #define EXTERNC
 #endif

 typedef void* mylibrary_mytype_t;

 EXTERNC mylibrary_mytype_t mylibrary_mytype_init();
 EXTERNC void mylibrary_mytype_destroy(mylibrary_mytype_t mytype);
 EXTERNC void mylibrary_mytype_doit(mylibrary_mytype_t self, int param);

 #undef EXTERNC
 // ...


 // *.cpp file
 mylibrary_mytype_t mylibrary_mytype_init() {
   return new MyType;
 }

 void mylibrary_mytype_destroy(mylibrary_mytype_t untyped_ptr) {
    MyType* typed_ptr = static_cast<MyType*>(untyped_ptr);
    delete typed_ptr;
 }

 void mylibrary_mytype_doit(mylibrary_mytype_t untyped_self, int param) {
    MyType* typed_self = static_cast<MyType*>(untyped_self);
    typed_self->doIt(param);
 }