gcc 4.4.4 c89
我刚刚阅读a discussion at DevX关于从C调用C ++代码,因为我必须做类似的事情。我只是想知道“make sure that non POD types in C++ are opaque to C clients.”
的用户Vijayan是什么意思非常感谢任何建议,
答案 0 :(得分:3)
C只能处理POD类型。
因此,您无法将非POD类型的对象传递给C程序(按值)。此外,如果将非POD类型的指针传递给C程序,它们也无法与指向的对象进行交互。
答案 1 :(得分:3)
POD =普通旧数据结构= C结构,没有虚拟方法等。您需要为C编写包装函数以访问非POD类型(即类)。
有关POD的更多信息: http://en.wikipedia.org/wiki/Plain_old_data_structure
答案 2 :(得分:2)
对于不透明的类型意味着你无法查看它内部:它是一个“黑盒子”,可以传递但不会被C代码直接检查或操作。您通常使用堆分配的内存和void * s来引用对象,或者使用函数来确定必要的长度和缓冲区。
例如,C ++对象可能包含std::string
,但是在C ++标准中未指定std::string
的布局,因此您无法编写直接读取或写入的C代码到字符串(至少,完全不了解std::string
布局,每次更新编译器/ STL时手动重新验证)。
因此,要允许C代码访问该对象,您可以编写C-callable函数,例如:
#if __cplusplus
extern "C" {
#endif
void* object_new();
const char* object_get_string(void* p_object);
void object_set_string(void* p_object, const char* s);
void object_delete();
#if _cplusplus
}
#endif
使用C ++实现ala:
class Object { std::string string_; ... }
void* object_new() { return new Object; }
const char* object_get_string(void* p) { return ((Object*)p)->string_.c_str()); }
...
这里,object_XXX函数为C代码提供了一种使用Object的安全方法。
答案 3 :(得分:2)
使类型不透明意味着,根据链接中的行:
typedef struct base base ; /* opaque */
使句柄的名称可用于C代码,但不是类型的定义。这意味着C代码不能直接访问任何成员,但必须通过接口函数。
请注意,您不必对通用(即void *)指针进行强制转换,但根据9dan的回答,这样做是一种选择。
请注意,即使在纯C代码中,这样的界面风格也是管理封装的一种非常好的方式,就像在标准C流库中一样。
答案 4 :(得分:1)
使客户变得不透明意味着没什么特别的。 C流文件I / O(FILE* f = fopen
)API是向客户端提供不透明句柄的典型示例。
显然C无法处理非POD类型,因此您必须从C客户端隐藏C ++实现,但提供访问方法。
示例:
class MyLibrary {
MyLibrary();
~MyLibrary();
int DoSomething();
...
}
typedef void* OPAQUEHANDLE;
extern OPAQUEHANDLE MyLibrary_OpenLibrary();
extern void MyLibrary_CloseLibrary(OPAQUEHANDLE h);
extern int MyLibrary_DoSometing(OPAQUEHANDLE h);
extern OPAQUEHANDLE MyLibrary_OpenLibrary()
{
return new MyLibrary;
}
extern void MyLibrary_CloseLibrary(OPAQUEHANDLE h)
{
delete (MyLibrary*) h;
}
extern int MyLibrary_DoSometing(OPAQUEHANDLE h)
{
return ((MyLibrary*)h)->DoSomething();
}