我在Linux中有两个共享库,它们在构建时在所有方面都是相同的,除了每个公开的一个函数具有不同的接口(一个接受一些第三方数组类型而另一个接受字符串)。我可以构建两个共享库版本,我想知道是否有一种方法可以将元信息插入共享库本身(就像你能够在构建时将注释/公司名称/等插入到DLL中一样) ,然后可以在运行时查询。
我不想以不同的方式命名两种.so文件,因为它们实际上是相同的,它们是较大系统的可互换部分。我需要我的代码在库上执行dlopen和dlsym以了解它的风格,以便它具有正确的接口。
我目前正在实现这一目标的方法是在一个中添加一个名为“Flavor_A”的无操作函数,在另一个中添加“Flavor_B”。然后,我将Flavor_A或Flavor_B用于验证我正在处理的共享库。如果我得到一个NULL,我知道Flavor_X不存在,在这种情况下它必须是另一种味道。
我认为必须有更好的方法。所以,这就是我在这里的原因。
有人建议如何在.so二进制文件本身中构建一些运行时可查询的信息吗?
感谢。
答案 0 :(得分:5)
我不建议使用两个不同的符号,而是建议使用一个始终存在的符号并返回正确的信息。
FLAVOR getFlavor()
{
#ifdef FLAVOR_A
return Flavor_A;
#else
return Flavor_B;
#endif
}
您也可以直接导出具有正确风味的变量;
extern FLAVOR flavor =
#ifdef FLAVOR_A
Flavor_A;
#else
Flavor_B;
#endif
对于后者,您可以像这样访问变量:
*(FLAVOR *)dlsym(lib, "flavor")
答案 1 :(得分:1)
为什么不添加GetFlavor / GetVersion方法,让您知道它是哪种风味/版本?
答案 2 :(得分:1)
您可以使用链接描述文件将任意注释部分等添加到ELF二进制文件中。链接器在运行时不会使用它们,但可以包含构建数据等信息。默认情况下,GCC会将一些内容用于说明使用的版本(例如.gnu.version)。
使用objdump检查或转储它们。
答案 3 :(得分:0)
这是最好的方法。除了符号之外,没有标准化的方法将东西放入.so中。