【发布时间】:2016-09-26 09:12:40
【问题描述】:
我目前有一个项目,其中不同的共享库链接在一起。 这些库的用户可以将他们自己的共享库添加到项目中。在所有这些库中,可以编写如下内容:
int a;
OBJECT(a)
double b;
OBJECT(b)
OBJECT 是一个宏,它收集有关链接的int、double 或任何其他类型/类的信息,并通过所有其他共享库中的公共接口使它们可用。它在所有库共享的标头中定义。
我现在想做的是确定在哪个共享库中调用了宏。
目前我在一个跨所有共享库共享的头文件中使用这样的东西:
Module& getModule();
#define MODULE(name) Module& getModule() { \
static Module mod{ #name }; \
return mod; \
}
这引入了一个声明和一个宏来提供定义。然后在每个共享库中,我只在一个 .cpp 中调用宏,每次都使用不同的名称来引入定义。这为每个共享库定义了一个 static Module mod;,每个共享库都有自己的名称。 OBJECT 宏在内部调用此函数以使用给定的Module“注册”自身。这样我就可以获得使用OBJECT 创建的所有对象的列表,按它们的Module 排序(按它们所在的共享库排序)。
使用 MSVC 可以正常工作。因为我没有在前面添加_declspec(dllimport/dllexport),所以我强制链接器链接到同一个共享库中给出的定义。但是在 Linux(gcc) 下这不起作用,并且所有 OBJECT 宏都使用单个共享库中的定义,这意味着我无法再识别宏在哪个库中被调用。
我知道,C++ 标准根本没有提及共享库,但我正在寻找一种“尽可能符合标准”或至少尽可能可移植的方式。
我考虑过使用一个只将“库名称”作为字符串返回的宏。但这意味着如果您包含其他库的标头,您需要确保它们不包含宏的定义或者包含/定义的顺序很重要,这两者在实践中都很难确定。
还有其他(聪明的)方法可以解决这个问题吗?
【问题讨论】:
-
两个小时前提出了同样的问题。出于好奇,您是一名测试工程师吗?
-
不,我正在为我们的物理研究小组开发一些实验室软件。你能链接我另一个问题吗?如果相同,我们可以删除这个。如果没有,我也许可以添加一些关于差异的内容。
-
有点类似。 Here it is.
-
嗯,不是真的。您链接的问题询问如何在通过 dlopen 加载库后获取库的名称/路径。我正在寻找的是一种在编译期间获取名称、任何用户定义的字符串或任何其他对该共享库唯一的方法。
-
在这种情况下,我的立场是正确的。
标签: c++ shared-libraries cross-platform