如何识别编译函数/对象的模块

时间:2016-09-26 09:12:41

标签: c++ shared-libraries cross-platform

我目前有一个项目,其中不同的共享库链接在一起。 这些库的用户可以将自己的共享库添加到项目中。在所有这些库中,人们可以编写如下内容:

int a;
OBJECT(a)

double b;
OBJECT(b)

OBJECT是一个宏,用于收集有关链接的intdouble或其他任何类型/类的信息,并通过所有其他共享库中的公共接口使其可用。它在所有库中共享的标头中定义。

我现在想做的是确定调用宏的共享库。

目前我在所有共享库共享的头文件中使用类似的东西:

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"作为一个字符串。但这意味着如果你包含其他库的标题,你需要确保它们要么不包含宏的定义,要么包含/定义的顺序,这两者都难以确定。实践。

还有其他(智能)方法可以解决这个问题吗?

1 个答案:

答案 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; \
}