我有一个包含以指向C++对象为参数的函数声明的头文件。实现部分在单独的C++文件中。我怎样才能在C中包含此头文件,并在C中使用这些函数,尽管参数需要是C++对象指针?
很不幸,我的第一次尝试回答了错误的问题...
针对您所提出的问题...
正如某位人士指出的那样,您可以传递 void *
。这也是我推荐的做法。就 C 而言,指向 C++ 对象的指针应该是完全不透明的。
如果 C++ 函数在全局命名空间中,它们也可以被标记为 extern "C"
。以下是一个示例:
myfunc.hpp:
#ifdef __cplusplus
extern "C" {
#endif
extern int myfunction(int, void *ob);
#ifdef __cplusplus
}
#endif
myfunc.cpp:
#include "myfunc.hpp"
void myfunction(int x, void *vobptr)
{
ClassType *ob = static_cast<ClassType *>(vobptr);
}
afoofile.c
#include "myfunc.hpp"
void frobble(int x, void *opaque_classtype_ptr) {
myfunction(x, opaque_classtype_ptr);
/* do stuff with buf */
}
typedef
的创造性用法来实现基本相同的功能。在我看来,这种方式非常丑陋,但以下是一个例子:#ifdef __cplusplus
extern "C" {
#else
typedef void ClassType; /* This is incredibly ugly. */
#endif
extern int myfunction(int, ClassType *ob);
#ifdef __cplusplus
}
#endif
myfunc.cpp:
#include "myfunc.hpp"
void myfunction(int x, ClassType *ob)
{
// Do stuff with ob
}
afoofile.c
#include "myfunc.hpp"
void frobble(int x, ClassType *opaque_classtype_ptr) {
myfunction(x, opaque_classtype_ptr);
/* do stuff with buf */
}
extern "C"
的情况下,更常见的习惯用法可以在我的回答中找到:http://stackoverflow.com/questions/2941126/c-explicit-dll-loading-first-chance-exception-on-non-extern-c-functions/2941360#2941360(它不适合放在评论中)。它不涉及重复原型,因此更不容易出现拼写错误。 - Ken Bloomstatic_cast
。另一种方法的丑陋之处在于,该函数根据看到声明的语言而采用不同的类型。对于普通指针类型,这可能不是问题。但对于函数指针类型,这可能会导致各种奇怪的事情发生。总的来说,像“丑陋的方式”那样玩快速和松散的类型系统只是一个坏主意。 - Omnifarious如果您的C代码只需要传递指针,并最终将其传回到一些实际处理它所指向对象的C ++中,您应该能够在C代码中使用void *
,并在返回到C ++时强制转换为T *
。
如果您计划让C代码实际使用指针,那么您几乎无法摆脱对编译器所做事情的反向工程,并尝试紧密模拟它以使事情正常运作。即使在最好的情况下,这也将是丑陋而脆弱的。
创建一个 C++ 的包装器模块,但其外部函数声明为extern "C"
。这将允许您从 C 代码中清晰地访问 C++ 代码。自然而然的,该包装器应该用void
指针(快速而肮脏的解决方案)或指向不完整的struct
类型(只要它们被一致使用,就会提供一定程度的类型安全性) 替换任何无法在 C 中表示的类型(即类)的指针。
不行,你必须创建一个与C兼容的抽象层:
typedef struct foowrapper *foohandle;
foohandle foo_create();
void foo_delete(foohandle);
int foo_getvalue(foohandle);
void foo_dosomething(foohandle, const char* str);
在阅读了关于这个主题的各种帖子后,我认为这是最容易理解的。
http://research.engineering.wustl.edu/~beardj/Mixed_C_C++.html
此外,在NetBeans中,示例可以直接运行,无需修改makefile文件。请查看此链接:
http://developers.sun.com/solaris/articles/mixing.html
该链接包含以下主题:
使用兼容的编译器
在C++源代码中访问C代码
- 从C源代码中访问C++代码
混合使用IO流和C标准IO
使用函数指针
处理C++异常
链接程序