我有一个应用程序(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/

10-11 22:45