繁体   English   中英

混合C / C ++代码会在共享库中产生“未定义符号”

[英]Mixing C/C++ code yields “undefined symbol” with shared library

这个问题使我困扰了一个星期,所以我认为可能终于是时候向你们寻求帮助了。 简而言之,这是一个故事:

我们正在内部使用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()方法(这将调用供应商的init方法,该方法将通过我们代码内的setter方法设置此“供应商插件”的名称/属性,将其称为plugin_set_name(args ...))

在共享头文件(shared.h)中(两个代码库都将使用此文件;我们将具有完整的结构定义,供应商将仅具有setter / getters的原型):

  • extern“ C” int plugin_set_name(args ...)

在供应商main.c文件中(使用gcc,-fPIC和-shared编译)

  • 如上所述的init()函数的实现

因此从本质上讲,发生的事情是C ++代码将使用dl调用从C .so库中加载init()函数,然后C .so库将调用C ++代码中定义的函数(在在这种情况下为plugin_set_name)。 这有可能吗? 由于它们是彼此独立且使用不同的编译器(gcc与g ++)进行编译的,因此两者之间不会相互链接。

我遇到的错误是在运行时:“未定义的符号:plugin_set_name”(因此它可以在库的init()方法中找到并获取它)。 当我使用gcc和直接C代码执行所有操作时,它可以完美地工作,所以我知道这不是代码,而是混合C / C ++的东西。 我也理解使用extern“ C”防止名称修饰,并使用nm / readelf确定没有任何类型的修饰。 有任何想法吗? 最好的方法是什么?

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

#ifdef __cplusplus
extern "C" {
#endif

plugin_set_name(args...)
other_shared_functions

#ifdef __cplusplus
}
#endif

我一直都这样。 无论哪种情况,它现在都可以用C编译供应商插件,而Qt和C ++编译服务器。 我认为问题在于所有外部元素的放置位置以及g ++链接标志(其中rdynamic至关重要)的组合。 谢谢。 只是将其放在此处,以防其他人遇到相同的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM