我知道這不是一個項目開發的好方法,但由於我工作的某些原因,我致力於將一些數據結構集成在C++(LRU緩存和哈希映射)中C項目。C代碼與C++數據結構
到目前爲止,我知道有一些方法可以使用extern "C"
來調用C++中的C函數,但是從C調用C++對象(方法...)呢?
我使用GCC。
我知道這不是一個項目開發的好方法,但由於我工作的某些原因,我致力於將一些數據結構集成在C++(LRU緩存和哈希映射)中C項目。C代碼與C++數據結構
到目前爲止,我知道有一些方法可以使用extern "C"
來調用C++中的C函數,但是從C調用C++對象(方法...)呢?
我使用GCC。
如果所有的代碼被用C++編譯器編譯應該沒有(或很少)的問題。
如果你的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);
}
+1非常完整的答案! –
寫在你的C++接口C包裝。將其編譯爲C++,但確保將您的C接口包含在extern "C"
塊中。這個新的界面應該與你的C程序很好地連接,並且讓你可以訪問你的C++代碼。
你需要創建一個帶作爲他們的第一個參數一個指向對象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);
}
+1,這個答案就是我正在學習的一個很好的例子。 –
不要忘記在頭文件的'extern「C''附近放置'#ifdef __cplusplus',這樣它們就可以從C中使用,並捕獲C++代碼中可能出現的任何異常(C不喜歡異常。 ..)。另外,不是使用'void *'作爲對象指針,人們可能想要轉發 - 聲明一個虛擬的'struct'以使類型安全性最小化。 – syam
據我所知,你不能。不是沒有爲C++函數提供C封裝,並將對象公開爲結構體/不透明指針。 (而且,在C++中使用指針是「邪惡的」。) – millimoose