C++ 混合C/C++;“代码收益率”;“未定义符号”;使用共享库

C++ 混合C/C++;“代码收益率”;“未定义符号”;使用共享库,c++,c,qt,shared-libraries,dlopen,C++,C,Qt,Shared Libraries,Dlopen,这个问题已经困扰了我一个星期了,所以我想也许是时候向你们寻求帮助了。以下是一个简单的故事: 我们正在内部使用Qt/C++开发一个嵌入式服务器。它是一个非常简单的服务器,可以处理客户端请求,并通过dlopen()/dlsym()调用加载适当的函数来执行特定于供应商的操作。这意味着供应商只需按照我们定义的方式向我们提供一个C中的.so文件及其功能(对我们来说是透明的)。这将是用C编写的,因为它需要做很多低级的事情,而我们的服务器是用Qt编写的,因为我们计划最终为它提供一个前端 下面是一些伪代码: 在

这个问题已经困扰了我一个星期了,所以我想也许是时候向你们寻求帮助了。以下是一个简单的故事:

我们正在内部使用Qt/C++开发一个嵌入式服务器。它是一个非常简单的服务器,可以处理客户端请求,并通过dlopen()/dlsym()调用加载适当的函数来执行特定于供应商的操作。这意味着供应商只需按照我们定义的方式向我们提供一个C中的.so文件及其功能(对我们来说是透明的)。这将是用C编写的,因为它需要做很多低级的事情,而我们的服务器是用Qt编写的,因为我们计划最终为它提供一个前端

下面是一些伪代码:

在我们的main.cpp文件中(这是以C方式编写的,但使用Qt mkspec中定义的g++编译器,使用-ldl和-rdynamic编译以导出所有符号):

  • dlopen()vendor.so文件(尝试使用RTLD_NOW和RTLD_LAZY)
  • dlsym()vendor.so init()方法(这将调用vendor的init方法,它将通过代码中的setter方法设置此“vendor plugin”的名称/属性,并调用此plugin\u set\u name(args…)
在共享头文件(shared.h)中(两个代码库都会使用它;我们的代码库会有完整的结构定义,供应商只会有setter/getter的原型):

  • 外部“C”int插件集名称(args…)
在vendor main.c文件中(使用gcc、-fPIC和-shared编译)

  • 上面提到的init()函数的实现

基本上,发生的是C++代码将使用DL调用从.so库加载Inter()函数,然后C .so库将调用C++代码中定义的函数(在这种情况下,插件是SuxIn StIsNeN名字)。这可能吗?两者都不是相互关联的,因为它们是独立编译的,并且使用不同的编译器(gcc与g++)编译的


我在运行时遇到的错误是:“undefined symbol:plugin_set_name”(因此它可以在库的init()方法中找到并进入)。当我使用gcc和直接的C代码来做任何事情时,它都能完美地工作,所以我知道这不是代码,而是混合了C/C++的东西。我还了解使用extern“C”来防止名称损坏,并使用nm/readelf来确定没有任何类型的损坏。有什么想法吗?最好的方法是什么?

不知怎么的,这在今天起了神奇的作用。我无法解释。我只是在共享头周围有外部“C”声明,所以在shared.h中:

#ifdef __cplusplus
extern "C" {
#endif

plugin_set_name(args...)
other_shared_functions

#ifdef __cplusplus
}
#endif

但是我一直都有这个。在这两种情况下,它现在都工作在供应商插件被编译在C和服务器在Qt和C++中编译。我认为问题在于如何放置所有外部以及g++链接标志(其中rdynamic至关重要)的组合。谢谢把这个放在这里,以防其他人遇到同样的问题。

我想你应该读一下:我已经用extern“C”(该示例显示的)预先编写了相关函数,但它仍然不起作用。我还通过使用g++在Qt之外手动编译,将Qt从方程中去掉,我也遇到了同样的问题。