如何从C调用C++方法?

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 当然,必须以某种方式找到该类的实例.

编辑:

关于其他答案中提到的一些问题:

  1. 在您的示例中,您编译main为C.这是未定义的行为,实际上可能意味着您的构造函数不会在静态对象上调用.(如果你的代码在DLL中,你就可以了.标准没有说明DLL的任何内容,但在实践中,它们可以工作.)

  2. 如果您通过异常报告错误,那么您必须更改签名以其他方式报告它们,并包装代码以捕获所有异常,并将它们转换为C约定.(由于您的函数没有返回值,因此可以通过返回代码轻松处理.)