首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为C++库编写C包装器?

为C++库编写C包装器?
EN

Stack Overflow用户
提问于 2015-09-08 04:48:29
回答 2查看 1.1K关注 0票数 0

C++11有sleep_for。但C标准并没有相应的。

我想我可以编写一个包装器来调用C中的C++函数。

还有一些有用的库,如Boost文件系统和Asio。这些比较复杂,但我也可以编写包装器。

会不会是在改造方向盘?会不会是个坏主意?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-09-08 04:53:33

这方面的一个问题是,如果您想编写调用Boost函数的C包装器,那么如果抛出异常怎么办?基本上,在调用者到达C之前,您必须在调用者中吞下它,但是正确地向C报告它是有点尴尬的,而且有很多类型的异常。

通常,当人们特别需要额外的可移植性或由于某种原因不能提供所有的C++依赖时,他们使用C而不是C++。如果您想编写一个使用boost::filesystem的C程序,为什么不把它编译成C++呢?您将有更少的异常处理锅炉板代码编写,更少的可能出错。

票数 2
EN

Stack Overflow用户

发布于 2015-09-08 07:35:44

zeroMQ就是这样做的。库是用C++编写的,但是库API是C接口。原则上,您可以将类隐藏在对象大小的内存块中,并传递void*。对于一些简单的函数,例如sleep_for,您可以创建一个包装器函数。在标题中,声明

代码语言:javascript
运行
复制
extern "C" {void sleep_for(int duration);}

在cpp-文件中,用std::this_thread::sleep_for实现这一点。

代码语言:javascript
运行
复制
sleep_for(int duration) {std::this_thread::sleep_for( std::chrono::milliseconds(duration);}

对于类,您需要C函数来创建一个新对象,对其进行析构,当然还需要调用成员函数。对于A类,这可能如下所示:

C头文件"A_C_API.h":

代码语言:javascript
运行
复制
extern "C" {
     enum {SIZE_OF_A = 4};
     typedef char[SIZE_OF_A] a_class;
     a_class initA(void* a, int x);
     void destructA(void* a);
     int callGet(void *a);
}

C++ source file:

class A {
public:
    A(int i): x{i} {}
    int get() const {return x;}
private:
    int x;
};

static_assert( SIZE_OF_A == sizeof(A), "size mismatch!");

void initA(void* a, int x) {
    new (a) A(x);
}

void destructA(void* a) {
    static_cast<A*>(a)->~A();        
}

int callGet(void *a) {
    return static_cast<A*>(a)->get();
}

在您的C应用程序中,您可以

代码语言:javascript
运行
复制
#include "A_C_API.h"
int main(int argc, char* argv[]) {
    a_class obj;
    initA(&obj);
    printf("%d", callGet(&obj) );
    destructA( &obj );
    return 0;
}

您必须捕获异常并将它们转换为某些C错误处理。您还必须处理一些平台上的对齐问题,特别是火花平台。为了简单起见,我省略了这一点,但是您可以查看zeromq头如何做到这一点。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32449424

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档