用C调用动态Cpp库

时间:2014-04-29 23:32:51

标签: c++ c shared-libraries

我的目标是能够为Cpp库创建一个C库包装器。

我有:

  1. libcpp.so,一个由其他人用Cpp编写的动态库
  2. libc.so,一个用C编写的动态库,用来包装libcpp
  3. test.c,一个测试它是否有效的简单问题。
  4. 我的问题是我无法正确编译libc.so,以便我可以从test.c访问libcpp.so中的功能

    示例代码:

    //libc.h
    extern "C" void * createNetwork();
    
    //libc.cpp
    #include "libc.h"
    #include <libcpp.h>  // <- unsure about this
    
    void * createObject()
    {
        Object * foo = new Object();
        void * retval = foo;
        return retval;
    }
    
    //test.c
    #include <stdio.h>
    void * createObject();
    
    int main()
    {
        void * bar = createObject();
        return 0;
    }
    

    我正在使用

    进行编译
    // COMPILE LIBC
    g++ -Wall -fPIC -c libc.cpp -L/opt/lib -llibcpp
    gcc -shared -Wl,-soname,libc.so.1 -o libc.so.1.0   *.o
    sudo mv libc.so.1.0 /opt/lib
    sudo ln -sf /opt/lib/libc.so.1.0 /opt/lib/libc.so.1
    sudo ln -sf /opt/lib/libc.so.1.0 /opt/lib/libc.so
    
    // COMPILE TEST.C
    gcc -Wall test.c -L/opt/lib -lc -o test
    

    如何在libc中正确包含libcpp?

    如何在test.c中正确包含libc?

    除了动态库之外,我还需要头文件吗?

2 个答案:

答案 0 :(得分:3)

创建C和C ++可调用函数的标准方法是使用预处理器条件查找__cplusplus,将整个头包装在extern "C"块中(如果已定义),并且不使用任何C ++扩展。
因此标题是C和C ++。 (如果定义了__cplusplus,可以选择有条件地添加静态和非虚函数以实现更好的C ++集成。

#ifdef __cplusplus
extern "C" {
#endif
  // Many functions
  // Forward-declarations of used classes using struct like this:
  typedef struct my_class myclass;
  // defined structs may include additional
  //  static and non-virtual member-functions if C++ defined
#ifdef __cplusplus
}
#endif

然后你可以在任何一个中构建你的库,虽然它应该促进对C ++库的调用,你应该使用C ++来构建一个健壮的库。
如果你包含标题但是忘记了C ++中的extern "C",编译器应该警告你。

答案 1 :(得分:2)

标准机制应如下所示:

<强> mylib.h:

#ifndef __cplusplus
extern "C" {
#endif

void * createThing();

void destroyThing(void *);

// more things to operate on the object

#ifndef __cplusplus
}  // extern "C"
#endif

<强> magic_lib.cpp:

#include "magic_thing.hpp"
#include "mylib.h"

void * createThing()
{ return new MagicThing; }

void destroyThing(void * p)
{ delete static_cast<MagicThing *>(p); }

用法(在C中)

#include "mylib.h"

int main(void)
{
    void * p = createThing();

    // ...  use p ...

    destroyThing(p);
}

如果您不喜欢无效指针,可以添加类似typedef void * ThingHandle左右的类型别名。