2015-09-08 28 views
0

C++ 11有sleep_for。但是C标准没有相应的标准。为C++库编写C封装器?

我认为可以编写一个包装从C.

调用这样的C++函数而有像提高文件系统和ASIO有用的库。这些更复杂,但我也可以写封装。

难道它是重新发明轮子?这可能是一个坏主意吗?

+0

看看http://stackoverflow.com/questions/264350/is-there-an-alternative-for-sleep-in-c – cup

回答

2

与此的一个问题是,如果你想用C写的包装,其调用升压功能,有什么事,如果抛出一个异常,你怎么办?你基本上不得不在调用者的C语言之前吞下它,但是当它正确地向C报告时有点尴尬,并且有很多类型的异常。

通常人们用C代替C++时,他们特别希望额外的便携性或无法提供因某些原因所有的C++依赖。如果你想编写一个使用boost :: filesystem的C程序,为什么不把它编译为C++呢?你将会有很少的异常处理锅炉板代码来编写,而且更少会出错。

+0

是将异常转换为代码并不优雅和不方便。当我已经有很多C代码,并且一些简单的C++函数正是我所需要的时候,我想我会使用包装器。 – cshu

2

zeroMQ这样做。库是用C++编写的,但库API是一个C接口。原则上,你隐藏对象大小的内存块中的类,并通过void*左右。对于一些简单的功能,例如sleep_for,你可以创建一个包装函数。在你的头文件中,声明

extern "C" {void sleep_for(int duration);} 

在你的cpp文件中,按照std::this_thread::sleep_for实现这个。

sleep_for(int duration) {std::this_thread::sleep_for(std::chrono::milliseconds(duration);} 

对于类,您需要C函数来创建一个新的对象,将其删除,当然也可以调用成员函数。对于A类,这可能如下所示:

C头文件 “A_C_API.h”:

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程序,然后你可以

#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错误处理。您还必须在某些平台上处理对齐问题,尤其是SPARK平台。为简单起见,我省略了这一点,但您可以查看zeromq头文件如何执行此操作。