简体   繁体   English

从C ++程序中的C库调用函数时是否有陷阱?

[英]Are there any pitfalls when calling functions from a C library in a C++ program?

I'm using a library which has both a C interface and a C++ interface in my C++ program. 我正在使用在C ++程序中同时具有C接口和C ++接口的库。 The C++ one is a bit immature and I must stick with the C one. C ++有点不成熟,我必须坚持使用C ++。 I was wondering, in more general terms, is there anything specific to keep in mind when mixing C-style binary object files with a C++ project? 我想知道,更笼统地说,在将C样式的二进制对象文件与C ++项目混合时,有什么要记住的特定事项吗?

For C functions to be called from C++, they have to be declared as extern "C" . 为了从C ++中调用C函数,必须将它们声明为extern "C" Usually something like this is used in headers: 通常在标头中使用如下所示的内容:

#if defined(__cplusplus)
extern "C" {
#endif

void f();
void g();

#if defined(__cplusplus)
}
#endif

C functions have to be declared as extern "C", if your C header files don't do this automatically, you can do it like this for the whole header: C函数必须声明为extern“ C”,如果您的C头文件没有自动执行此操作,则可以对整个头文件执行以下操作:

extern "C"
{
    #include "c-library.h"
}

Otherwise, as long as you use a C++ linker for everything all will be fine :). 否则,只要您对所有内容都使用C ++链接器就可以了:)。

One thing that is very useful when dealing with C libraries from C++ is RAII . RAII是处理来自C ++的C库时非常有用的一件事。 Say if your C library has an initialization and release functions, that could be easily wrapped into resource-managing class: 假设您的C库具有初始化和发布功能,则可以轻松地将其包装到资源管理类中:

#include <boost/utility.hpp>

/// Base class for top-level library objects
class lib_base: boost::noncopyable
{
protected:

    lib_base()
    {
        if ( my_c_lib_init() == -1 )
            throw std::runtime_error( "no C lib" );
    }

    ~lib_base() { my_c_lib_fini(); }
};

/// Widget from C library
class widget: lib_base
{
public:

    widget( const std::string& name ) :
        lib_base(), pcw_()
    {
        if (( pcw_ = my_c_lib_alloc_widget( name.c_str())) == NULL )
            throw std::runtime_error( "no more widgets" );
    }

    ~widget() { my_c_lib_release_widget( pcw_ ); }

private:

    c_widget* pcw_; //< low-level widget
};

This of course makes the child class non-copyable, but that can be worked around via containment and/or smart pointers. 当然,这会使子类不可复制,但是可以通过包含和/或智能指针来解决。

Calling C functions from C++ programs is pretty common. 从C ++程序调用C函数非常普遍。 There is only one thing to keep in mind - use a C++ linker :) Also keep in mind that C functions cannot use exceptions, so you have to check their return values. 要记住的只有一件事-使用C ++链接器:)也要记住C函数不能使用异常,因此您必须检查它们的返回值。

Edit: others have pointed out that C function declarations should be wrapped in extern "C" {...} . 编辑:其他人指出,C函数声明应该用extern "C" {...}包装。 Usually this is already done in library header files. 通常,这已经在库头文件中完成了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM