在C ++程序中从C库调用函数时是否存在任何缺陷?

时间:2010-04-13 13:00:28

标签: c++ c

我正在使用一个在我的C ++程序中同时具有C接口和C ++接口的库。 C ++有点不成熟,我必须坚持使用C语言。我想知道,更笼统地说,在将C风格的二进制目标文件与C ++项目混合时,有什么特别需要记住的吗?

4 个答案:

答案 0 :(得分:5)

对于要从C ++调用的C函数,必须将它们声明为extern "C"。通常在标题中使用这样的东西:

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

void f();
void g();

#if defined(__cplusplus)
}
#endif

答案 1 :(得分:2)

C函数必须声明为extern“C”,如果您的C头文件不自动执行此操作,您可以像这样对整个标题执行:

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

否则,只要您使用C ++链接器,一切都会没问题。)。

答案 2 :(得分:1)

从C ++处理C库时,有一件非常有用的事情是RAII。假设您的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
};

这当然会使子类不可复制,但可以通过包含和/或智能指针来解决。

答案 3 :(得分:0)

从C ++程序调用C函数非常常见。只需要记住一件事 - 使用C ++链接器:)还要记住C函数不能使用异常,所以你必须检查它们的返回值。

编辑:其他人指出C函数声明应该包含在extern "C" {...}中。通常这已在库头文件中完成。