开发者

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. The C++ one is a bit immature and I must stick with the C one. I was wondering, in more general terms, is there anything speci开发者_StackOverflowfic to keep in mind when mixing C-style binary object files with a C++ project?


For C functions to be called from C++, they have to be declared as 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:

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

Otherwise, as long as you use a C++ linker for everything all will be fine :).


One thing that is very useful when dealing with C libraries from C++ is RAII. Say if your C library has an initialization and release functions, that could be easily wrapped into resource-managing class:

#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. 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.

Edit: others have pointed out that C function declarations should be wrapped in extern "C" {...}. Usually this is already done in library header files.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜