tot*_*ten 9 c c++ class extern
我有一个C++类,我正在用一些C文件编译它.
我想调用一个用C++定义的函数,实际上是在C++类中,所以我该怎么做?
以下声明显示我在说什么:可能存在语法错误:
serial_comm.cpp
class MyClass {
void sendCommandToSerialDevice(int Command, int Parameters, int DeviceId) {
//some codes that write to serial port.
}
}
Run Code Online (Sandbox Code Playgroud)
external.c
int main(int argc, char ** argv) {
//what am I going to write here?
}
Run Code Online (Sandbox Code Playgroud)
Dav*_*eas 19
解决此问题的常见方法是提供C包装器API.编写一个C函数,它接受一个指向MyClass对象的指针(因为MyClass它不是有效的C,你需要提供一些名字,最简单的就是void*四处移动)和其余的参数.然后在C++里面执行函数调用:
extern "C" void* MyClass_create() {
return new MyClass;
}
extern "C" void MyClass_release(void* myclass) {
delete static_cast<MyClass*>(myclass);
}
extern "C" void MyClass_sendCommandToSerialDevice(void* myclass, int cmd, int params, int id) {
static_cast<MyClass*>(myclass)->sendCommandToSerialDevice(cmd,params,id);
}
Run Code Online (Sandbox Code Playgroud)
然后C代码使用C api创建对象,调用函数并释放对象:
// C
void* myclass = MyClass_create();
MyClass_sendCommandToSerialDevice(myclass,1,2,3);
MyClass_release(myclass);
Run Code Online (Sandbox Code Playgroud)
Jam*_*nze 10
你必须传递一个额外的参数,用对象的地址来调用函数.就像是:
extern "C" void SendCommandToSerialDevice( void* object,
int command, int parameters, int deviceId )
{
static_cast<MyClass*>( object)->sendCommandToSerialDevice(
command, parameters, deviceId );
}
Run Code Online (Sandbox Code Playgroud)
main 当然,必须以某种方式找到该类的实例.
关于其他答案中提到的一些问题:
在您的示例中,您编译main为C.这是未定义的行为,实际上可能意味着您的构造函数不会在静态对象上调用.(如果你的代码在DLL中,你就可以了.标准没有说明DLL的任何内容,但在实践中,它们可以工作.)
如果您通过异常报告错误,那么您必须更改签名以其他方式报告它们,并包装代码以捕获所有异常,并将它们转换为C约定.(由于您的函数没有返回值,因此可以通过返回代码轻松处理.)