用C语言调用动态Cpp库

Using C to Call Dynamic Cpp Library

本文关键字:Cpp 动态 调用 语言      更新时间:2023-10-16

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

我有:

  1. libcpp.so,其他人用Cpp编写的动态库
  2. libc.so,我用C编写的一个动态库,用于包装libcpp
  3. test.c,一个简单的问题来测试它是否有效

我的问题是,我无法正确编译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?

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

创建可由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",编译器应该警告您。

标准机制应该是这样的:

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);
}

如果你不喜欢void指针,你可以添加一个类型别名,比如typedef void * ThingHandle左右。