【问题标题】:How to identify in which module a function/object is compiled如何识别函数/对象在哪个模块中编译
【发布时间】:2016-09-26 09:12:40
【问题描述】:

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

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++ 标准根本没有提及共享库,但我正在寻找一种“尽可能符合标准”或至少尽可能可移植的方式。

我考虑过使用一个只将“库名称”作为字符串返回的宏。但这意味着如果您包含其他库的标头,您需要确保它们不包含宏的定义或者包含/定义的顺序很重要,这两者在实践中都很难确定。

还有其他(聪明的)方法可以解决这个问题吗?

【问题讨论】:

  • 两个小时前提出了同样的问题。出于好奇,您是一名测试工程师吗?
  • 不,我正在为我们的物理研究小组开发一些实验室软件。你能链接我另一个问题吗?如果相同,我们可以删除这个。如果没有,我也许可以添加一些关于差异的内容。
  • 有点类似。 Here it is.
  • 嗯,不是真的。您链接的问题询问如何在通过 dlopen 加载库后获取库的名称/路径。我正在寻找的是一种在编译期间获取名称、任何用户定义的字符串或任何其他对该共享库唯一的方法。
  • 在这种情况下,我的立场是正确的。

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


【解决方案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; \
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-06
    • 1970-01-01
    • 1970-01-01
    • 2021-11-27
    • 2015-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多