2013-05-27 64 views
5

我知道这不是一个项目开发的好方法,但由于我工作的某些原因,我致力于将一些数据结构集成在C++(LRU缓存和哈希映射)中C项目。C代码与C++数据结构

到目前为止,我知道有一些方法可以使用extern "C"来调用C++中的C函数,但是从C调用C++对象(方法...)呢?

我使用GCC。

+1

据我所知,你不能。不是没有为C++函数提供C封装,并将对象公开为结构体/不透明指针。 (而且,在C++中使用指针是“邪恶的”。) – millimoose

回答

6

如果所有的代码被用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); 
} 
+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