A .So Link Problem

在gazebo插件开发的时候遇到的动态链接库的链接问题。

场景

  1. 编译building_sim_common包,里面包含该插件的一些相关的类定义,其中包含一个template模板函数
  2. 编译building_sim_gazebo包,这是该插件真正的定义,在这个插件中使用了building_sim_common中定义的类
  3. 现在发现building_sim_gazebo中有一些定义可以转移到building_sim_common中,于是将这部分定义转移到building_sim_common中,出现运行时链接错误

所找到的问题

  1. 类模板和模板函数链接出错处理:
    https://blog.csdn.net/gettogetto/article/details/51428511
  • 对C++编译器而言,当调用函数的时候,编译器只需要看到函数的声明。当定义类类型的对象时,编译器只需要知道类的定义,而不需要知道类的实现代码。因此,因该将类的定义和函数声明放在头文件中,而普通函数和类成员函数的定义放在源文件中。
  • 但在处理模板函数和类模板时,问题发生了变化。要进行实例化模板函数和类模板,要求编译器在实例化模板时必须在上下文中可以查看到其定义实体;而反过来,在看到实例化模板之前,编译器对模板的定义体是不处理的——原因很简单,编译器怎么会预先知道 typename 实参是什么呢?因此模板的实例化与定义体必须放到同一翻译单元中。

所以为了容易使用,总是在头文件中放置全部的模板声明和定义,不会分开去放!!!

  1. 链接的时候可能出现的问题:
    假设我们知道链接是undefined symbol就在xxx.so文件中,虽然使用了makefile加上了xxx.so的依赖,但是一定要把xxx.so放在最后面,因为有可能.so依赖的其他库也用了xxx.so。
    这个在cmake使用环境下可能并不存在,但是也可能其中的一个解决方向。