如何识别function/object在哪个模块中编译
How to identify in which module a function/object is compiled
我目前有一个项目,其中将不同的共享库 link 整合在一起。
这些库的用户能够将他们自己的共享库添加到项目中。在所有这些库中,人们可以这样写:
int a;
OBJECT(a)
double b;
OBJECT(b)
OBJECT
是一个宏,它收集有关 linked int
、double
或任何其他 type/class 的信息,并使它们可以通过公共所有其他共享库中的接口。它在所有库共享的 header 中定义。
我现在想做的是确定在哪个共享库中调用了宏。
目前我在所有共享库共享的 header 文件中使用类似的东西:
Module& getModule();
#define MODULE(name) Module& getModule() { \
static Module mod{ #name }; \
return mod; \
}
这引入了声明和宏来提供定义。然后在每个共享库中,我只在一个 .cpp 中调用宏,每次都使用不同的名称来引入定义。这为每个共享库定义了一个 static Module mod;
,每个共享库都有自己的名称。 OBJECT
宏使用给定的 Module
在内部将此函数调用到 "register" 本身。通过这种方式,我可以获得使用 OBJECT
创建的所有 objects 的列表,按它们的 Module
排序(按它们所在的共享库排序)。
对于 MSVC,这工作正常。因为我没有在前面添加 _declspec(dllimport/dllexport)
,所以我强制 linker 到 link 到同一共享库中给出的定义。但是在 Linux(gcc) 下这不起作用,所有 OBJECT
宏都使用单个共享库中的定义,这意味着我无法再识别调用宏的库。
我知道,C++ 标准根本没有说明共享库,但我正在寻找的是一种 "as standard compliant as possible" 或至少尽可能可移植的方式。
我考虑过使用一个仅将 returns 和 "libary name" 作为字符串的宏。但这意味着如果你包含其他库的 headers,你需要确保它们要么不包含宏的定义,要么 include/definition 的顺序很重要,两者都是实践中很难确定。
还有其他(聪明的)方法可以解决这个问题吗?
一个简单的解决方案,即使在 Linux 上也能工作,就是将这个 Module
静态函数标识符放在你 link 的每个库中,但隐藏它以便默认不导出它:
#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; \
}
我目前有一个项目,其中将不同的共享库 link 整合在一起。 这些库的用户能够将他们自己的共享库添加到项目中。在所有这些库中,人们可以这样写:
int a;
OBJECT(a)
double b;
OBJECT(b)
OBJECT
是一个宏,它收集有关 linked int
、double
或任何其他 type/class 的信息,并使它们可以通过公共所有其他共享库中的接口。它在所有库共享的 header 中定义。
我现在想做的是确定在哪个共享库中调用了宏。
目前我在所有共享库共享的 header 文件中使用类似的东西:
Module& getModule();
#define MODULE(name) Module& getModule() { \
static Module mod{ #name }; \
return mod; \
}
这引入了声明和宏来提供定义。然后在每个共享库中,我只在一个 .cpp 中调用宏,每次都使用不同的名称来引入定义。这为每个共享库定义了一个 static Module mod;
,每个共享库都有自己的名称。 OBJECT
宏使用给定的 Module
在内部将此函数调用到 "register" 本身。通过这种方式,我可以获得使用 OBJECT
创建的所有 objects 的列表,按它们的 Module
排序(按它们所在的共享库排序)。
对于 MSVC,这工作正常。因为我没有在前面添加 _declspec(dllimport/dllexport)
,所以我强制 linker 到 link 到同一共享库中给出的定义。但是在 Linux(gcc) 下这不起作用,所有 OBJECT
宏都使用单个共享库中的定义,这意味着我无法再识别调用宏的库。
我知道,C++ 标准根本没有说明共享库,但我正在寻找的是一种 "as standard compliant as possible" 或至少尽可能可移植的方式。
我考虑过使用一个仅将 returns 和 "libary name" 作为字符串的宏。但这意味着如果你包含其他库的 headers,你需要确保它们要么不包含宏的定义,要么 include/definition 的顺序很重要,两者都是实践中很难确定。
还有其他(聪明的)方法可以解决这个问题吗?
一个简单的解决方案,即使在 Linux 上也能工作,就是将这个 Module
静态函数标识符放在你 link 的每个库中,但隐藏它以便默认不导出它:
#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; \
}