我目前有一个项目,其中不同的共享库链接在一起。
这些库的用户可以将自己的共享库添加到项目中。在所有这些库中,人们可以编写如下内容:
int a;
OBJECT(a)
double b;
OBJECT(b)
OBJECT
是一个宏,它收集有关链接的int
,double
或任何其他类型/类的信息,并通过所有其他共享库中的公共(public)接口(interface)使它们可用。它在所有库之间共享的 header 中定义。我现在想做的是确定在哪个共享库中调用了宏。
目前,我在所有共享库之间共享的头文件中使用了类似的方法:
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++标准根本没有提及共享库,但是我正在寻找的是一种“尽可能符合标准”或至少尽可能可移植的方式。
我考虑过使用只返回“库名”作为字符串的宏。但这意味着如果包含其他库的 header ,则需要确保它们也不包含宏的定义或包含/定义事项的顺序,这在实践中都很难确定。
还有其他(智能)方法可以解决此问题吗?
最佳答案
一个即使在Linux上也可以使用的简单解决方案是将该Module
静态函数标识符放入您链接的每个库中,但将其隐藏起来,因此默认情况下不会导出:
#ifdef _WIN32
#define DLL_LOCAL
#elif __linux__
#define DLL_LOCAL __attribute__ ((visibility ("hidden")))
#endif
#define MODULE(name) DLL_LOCAL Module& getModule() { \
static Module mod{ #name }; \
return mod; \
}
关于c++ - 如何识别功能/对象在哪个模块中编译,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39698846/