2013-05-27 12 views
5

これはプロジェクトの開発には適していませんが、私の仕事の理由から、C++(LRUキャッシュとハッシュマップ)でいくつかのデータ構造をCプロジェクト。CコードのC++データ構造

これまでのところ、C++でCの関数を呼び出すには、extern "C"を使用する方法がありますが、C++オブジェクト(メソッド...)をCから呼び出す方法はありますか?

私はGCCを使用しています。

+1

私の知る限り、あなたがすることはできません。 C++関数のCラッパーを提供せず、オブジェクトを構造体/不透明ポインタとして公開することもありません。 (そして、C++のポインタは "悪"です。) – millimoose

答えて

6

すべてのコードがC++コンパイラでコンパイルされている場合、問題はない(またはごくわずかです)。

gccでコンパイルしたC++とg ++でコンパイルしたC++を使用する場合は、クラスの周りにヘッダラッパーを作成して、一連の関数を介してC++コードを見えるようにする必要があります。

例:

MyClass.h

#ifdef __cplusplus 


class MyClass 
{ 
    public: 
     MyClass() {/*STUFF*/} 
     ~MyClass() {/*STUFF*/} 

     int doStuff(int x, float y) {/*STUFF*/} 
}; 

extern "C" { 
#endif 

/* C Interface to MyClass */ 

void* createMyClass(); 
void destroyMyClass(void* mc); 
int  doStuffMyClass(void* mc, int x, float y); 

#ifdef __cplusplus 
} 
#endif 

ソースファイル

MyClass.cpp

#include "MyClass.h" 

void* createMyClass()   {return reinterpret_cast<void*>(new MyClass);} 
void destroyMyClass(void* mc) {delete reinterpret_cast<MyClass*>(mc);} 

int  doStuffMyClass(void* mc, int x, float y) 
{ 
    return reinterpret_cast<MyClass*>(mc)->doStuff(x,y); 
} 

あなたのCコードは今だけ "MyClass.h" を含め、使用しています提供されるC関数。

MyCFile.c

#include "MyClass.h" 

int main() 
{ 
    void* myClass = createMyClass(); 
    int value = doStuffMyClass(myClass, 5, 6.0); 
    destroyMyClass(myClass); 
} 
+0

+1非常に完全な答え! –

6

C++インターフェイスにCラッパーを記述します。 C++としてコンパイルしますが、Cインタフェースをextern "C"ブロックに含めてください。この新しいインタフェースは、Cプログラムとうまくリンクし、C++コードへのアクセスを提供する必要があります。

5

最初のパラメータとしてオブジェクトへのポインタをとるC互換転送関数を作成する必要があります。転送関数は、最初のパラメータを正しいオブジェクト型にキャストし、適切なメンバ関数を呼び出します。

// Function declaration in header 
extern "C" void function(void *object, int param1, int param2); 

// Function definition in source file 
extern "C" function(void *object, int param1, int param2) 
{ 
    static_cast<Object*>(object)->member_function(param1, param2); 
} 
+0

+1、この回答は私が得ているものの良い例です。 –

+2

ヘッダーの 'extern" C ""の前後で '#ifdef __cplusplus'を忘れずにCから使用できるようにし、C++コードで発生する可能性のある例外をキャッチします(Cは例外を好きではありません)。 ..)。また、オブジェクトポインタに 'void *'を使用するのではなく、最小限の型安全性を持つようにダミー 'struct 'を前方宣言したいかもしれません。 – syam