为什么延迟链接选项导致clang"非法数据引用"错误?

时间:2016-05-13 03:23:36

标签: c++ macos linker clang dylib

使用"延迟链接"链接选项" -lazy-lz"在this question中引用以延迟加载依赖动态库,Xcode 7.2.1(Apple LLVM版本7.0.2(clang-700.1.81))的链接器生成此错误:

ld: illegal data reference to __ZN9WBRefSpecD1Ev in lazy loaded dylib

...其中受损的C ++符号引用我的单类dylib中的类析构函数:_WBRefSpec :: ~WBRefSpec()

我无法在任何地方找到直接引用,以指出此错误可能意味着什么 - 或者可能导致错误的原因。

在.cpp文件中,定义了析构函数:

EXPORT WBRefSpec::~WBRefSpec(void)
{
    ClearEntireRefSpec();  // commenting out this call doesn't affect error message!
}

......其中EXPORT是通常的:

#define EXPORT __attribute__((visibility("default")))

...当然,在头文件中定义为类的公共成员:

〜WBRefSpec(无效);

有人见过这个或者有什么原因导致这个错误吗?

编辑/答案:

非法数据引用的答案是WAS .cpp文件定义了一个类成员函数,声明了"静态WBRefSpec foo;"删除了,并且宾果游戏,没有链接错误。

(删除了链接详细信息,因为它们与问题无关)

1 个答案:

答案 0 :(得分:0)

非法数据引用的答案是有一个.cpp文件,其中定义了一个类成员函数,声明为“static WBRefSpec foo;”

WBRefSpec& XMLErrorLogFile::GetLogFileInAppFolder()
{
    static WBRefSpec logFileInAppFolder;
    return logFileInAppFolder;
}

作为测试,我删除了静态和宾果游戏,没有链接错误。

但是注意:在这种情况下只编辑“静态”会产生一个非常糟糕的想法并创建另一个非常严重的问题:返回对堆栈上分配的对象的引用!

我认为如果我创建一个静态WBRefSpec *的类数据成员,并在我的函数中初始化它(但只有一次),那么问题也会消失。

具有讽刺意味的是,我根据对其他人的unrelated posting的优秀答案选择了这种模式。