8

我正在创建一个仅模板的 C++ 库。但是,我还想提供一个“空”共享库,以便通过控制 SONAME,我可以在模板发生变化时强制重建模板消费者,从而导致实例化模板 ABI 不兼容。

可悲的是,如果一个特定的用户-Wl,--as-needed在他LDFLAGS的 中,链接器将从中删除我的共享库,NEEDED因为编译的可执行文件没有从它请求任何符号。如何确保程序始终与我的库链接,最好不要引入不必要的虚拟函数调用(或者如果必须,使它们的负担最小)?

编辑:作为说明,特定的模板类提供静态方法,通常只使用那些静态方法。因此,依赖构造函数中的任何内容都不是一个好主意,我真的很想避免通过某种强制执行来加重所有方法的负担。


@EmployedRussian的启发,我实现了:

extern int dummy;

namespace
{
    struct G
    {
        inline G()
        {
            dummy = 0;
        }
    };

    static const G g;
}

但遗憾的是,它为每个单元(包括头文件)执行一次分配。

4

2 回答 2

4

但是,我还想提供一个“空”共享库,以便通过控制 SONAME,只要模板发生变化导致实例化模板 ABI 不兼容,我就可以强制重建模板消费者。

这将在运行时强制出错。

您可以在不使用SONAME. 在您的模板标题之一中,放入一个将在运行时的全局对象

  1. 取地址或致电libmysolib_version_<N>,或
  2. dlopen(libmysolib.so, ...)dlsym("libmysolib_version_<N>", ...)

N然后在每次破坏 ABI 时保持递增。

最好不要引入不必要的虚拟函数调用

取地址libmysolib_version_<N>不调用函数;它只是强制运行时链接器找到该符号一次(在启动时)。您可能会与链接器垃圾收集发生冲突。

于 2012-08-12T18:02:39.657 回答
2

我推荐一种替代方法:

myheader.h 

namespace mylib_1 {
   void foo(); 
   //all the code goes there
}
namespace mylib = mylib_1;

用户调用:

mylib::foo()

使用不同 myheader 版本的代码不会链接,因为它会更改函数的签名。

ICU使用这种方法

于 2012-08-25T05:57:07.777 回答