我正在使用一个在我的C ++程序中同时具有C接口和C ++接口的库。 C ++有点不成熟,我必须坚持使用C语言。我想知道,更笼统地说,在将C风格的二进制目标文件与C ++项目混合时,有什么特别需要记住的吗?
答案 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" {...}
中。通常这已在库头文件中完成。