如何调用从C C ++的方法? [重复](How to call a C++ method fr

2019-07-19 17:58发布

这个问题已经在这里有一个答案:

  • 从“C”代码中调用“C ++”类的成员函数 1个回答

我有一个C ++类,我有一些C编译的文件它。

我想打电话给它在C ++中定义的函数,实际上C ++类,所以我要去怎么办?

以下声明,以显示我说什么:有可能会有语法错误:

serial_comm.cpp

class MyClass {
    void sendCommandToSerialDevice(int Command, int Parameters, int DeviceId) {
         //some codes that write to serial port.
    }
}

external.c

int main(int argc, char ** argv) {
    //what am I going to write here?
}

Answer 1:

解决这个问题的常见的方法是提供一个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);
}

那么C代码使用C API来创建对象,调用函数与释放对象:

// C
void* myclass = MyClass_create();
MyClass_sendCommandToSerialDevice(myclass,1,2,3);
MyClass_release(myclass);


Answer 2:

你必须通过一个额外的参数,与对象的地址来调用该函数。 就像是:

extern "C" void SendCommandToSerialDevice( void* object,
    int command, int parameters, int deviceId )
{
    static_cast<MyClass*>( object)->sendCommandToSerialDevice(
        command, parameters, deviceId );
}

main的意志,当然,必须以某种方式找到的类的实例。

编辑:

至于在其他的答案带来了一些要点:

  1. 在你的榜样,您编译main为C.这是不确定的行为,并在实践中可能意味着你的构造不会在静态对象调用。 (如果你的代码是一个DLL,你确定。该标准不说的DLL的事情,但在实践中,他们的工作。)

  2. 如果你用异常的方式报告错误,那么你就必须改变你的签名在一些其他的方式来报告他们,包装你的代码来捕获所有异常,并将它们转换为C约定。 (因为你的函数没有返回值,这是很容易的返回码的手段来处理。)



Answer 3:

如果你想这样做正确

serial_comm_wrapper.h

#ifdef __cpluscplus
class MyClass;
extern "C" {
#else
struct MyClass;
typedef struct MyClass MyClass;
#endif

MyClass *MyClass_new();

void MyClass_sendCommandToSerialDevice(MyClass *instance, int Command, int Parameters, int DeviceId);

#ifdef __cpluscplus
}
#endif

serial_comm_wrapper.cc

#include "serial_comm_wrapper.h"
#include "serial_comm.hh"

MyClass *MyClass_new()
{
    return new MyClass();
}

void MyClass_sendCommandToSerialDevice(MyClass *instance, int Command, int Parameters, int DeviceId)
{
    instance->sendCommandToSerialDevice(command, Parameters, DeviceID);
}

external.c

#include "serial_comm_wrapper.h"

int main(int argc, char ** argv) {
     MyClass *instance = MyClass_new();
     MyClass_sendCommandToSerialDevice(instance, ...);
}


Answer 4:

你不能只是去调用从C C ++代码

您将需要产生一个C ++接口,可以从C调用

像这样的事情

 // interface.h

 #ifdef __cplusplus
 extern "C" {
 #endif

 void createMyclass();

 void callMyclassSendCommandToSerialDevice(int Command, int Parameters, int DeviceId);

 void destroyMyclass();

 #ifdef __cplusplus
 extern }
 #endif

然后,你这样做:

 static MyClass *myclass;

 void createMyclass()
 {
    try
    {
        myclass = new MyClass;
    }
    catch(...)
    {
       fprintf(stderr, "Uhoh, caught an exception, exiting...\n");
       exit(1);
    }
 }


 void callMyclassSendCommandToSerialDevice(int Command, int Parameters, int DeviceId)
 {
     // May need try/catch here. 
     myclass->sendCommandToSerialDevice(Command, Parameters, DeviceId);
 }

 void destroyMyclass()
 {
    delete myclass;
 }

请注意,它的当务之急是你不要让“例外”穿墙的C代码,因为这是明确的未定义的行为。



Answer 5:

您不能直接在C调用C ++方法相反,你可以创建一个C包装,然后调用:

C / C ++兼容头文件:

#ifdef __cplusplus
extern "C" {
#endif

struct MyClass;

MyClass *new_MyClass();

void MyClass_sendCommandToSerialDevice(MyClass *c, int Command, int Parameters, int DeviceID);

#ifdef __cplusplus
} // extern "C"
#endif

实现(.cpp文件)

#include "my_c_compatiblity_header.h"
#include "MyClass.h"

extern "C" MyClass *new_MyClass() { return new MyClass(); }

extern "C"
void MyClass_sendCommandToSerialDevice(MyClass *c, int Command, int Parameters, int DeviceID) {
    c->sendCommandToSerialDevice(Command, Parameters, DeviceID);
}

main.c中

int main(int argc, char ** argv) {
    MyClass *c = new_MyClass();
    MyClass_sendCommandToSerialDevice(c, 1, 0, 123);
}

当然,由于资源和错误处理可以是C和C ++不同的代码,你就必须制定出如何处理你的情况相结合。 例如上面只是一个泄漏MyClass对象,而不是清理,并没有做有关异常的事情。



文章来源: How to call a C++ method from C? [duplicate]
标签: c++ c class extern