我有一个应用程序(app)和一个动态库/共享库(dlib),它们都与静态库链接,该静态库使用__declspec (selectany)
/__attribute__ ((weak))
在头文件中声明了全局变量(gvar)。通过设计,app和dlib都应该拥有自己的gvar拷贝(在MSVC和GCC上我完全可以做到这一点)。
移植到Mac OSX并使用clang编译后,我看到dlib中的gvar已链接到应用程序中的gvar。不确定这是Clang错误还是设计使然;如果是设计使然,有什么办法可以避免它并获得与GCC/MSVC相同的行为?
lang版本:
bash-3.2$ c++ --version
Apple LLVM version 7.0.0 (clang-700.1.76)
Target: x86_64-apple-darwin15.0.0
Thread model: posix
重现该问题的最小项目:
main.cpp:
#include <stdio.h>
#include <dlfcn.h>
__attribute__ ((weak)) int g_global = 10;
int main ()
{
printf ("main (): g_global: addr = %p; value = %d\n", &g_global, g_global);
typedef void Foo ();
void* so = dlopen ("./my-so.so", RTLD_LAZY | RTLD_LOCAL);
Foo* foo = (Foo*) dlsym (so, "foo");
foo ();
}
shared.cpp:
#include <stdio.h>
__attribute__ ((weak)) int g_global = 20;
extern "C" void foo ()
{
printf ("foo (): g_global: addr = %p; value = %d\n", &g_global, g_global);
}
build.sh:
#!/bin/bash
rm -f my-so.so
rm -f app.
c++ -shared -fPIC shared.cpp -omy-so.so
c++ main.cpp -oapp -ldl
输出:
bash-3.2$ ./app
main (): g_global: addr = 0x10c657030; value = 10
foo (): g_global: addr = 0x10c657030; value = 10
请注意,如果我删除属性((弱)),则app和dlib将获得其自己的gvar拷贝。
最佳答案
我在这里找到了答案:
https://gcc.gnu.org/wiki/Visibility
要获得我想要的行为,我必须在命令行中添加-fvisibility=hidden
,并将__attribute__ ((visibility ("default")))
添加到需要导出的符号中。
关于c++ - __attribute__((weak))的处理在clang和gcc中是不同的,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33751909/