我目前有一个项目,其中不同的共享库链接在一起。 这些库的用户可以将自己的共享库添加到项目中。在所有这些库中,人们可以编写如下内容:
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 ++标准根本没有关于共享库的任何内容,但我正在寻找的是一种尽可能符合标准的方式"或者至少尽可能便携。
我想过使用一个只返回" libary name"作为一个字符串。但这意味着如果你包含其他库的标题,你需要确保它们要么不包含宏的定义,要么包含/定义的顺序,这两者都难以确定。实践。
还有其他(智能)方法可以解决这个问题吗?
答案 0 :(得分:1)
一个简单的解决方案,即使在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; \
}