【问题标题】:Linker issues in C++ / ObjCC++ / ObjC 中的链接器问题
【发布时间】:2011-04-01 13:35:52
【问题描述】:

我正在将一个相当大的代码库移植到 iOS。我的场景的简化版本如下:

  • 我有一个从命令行构建的 C++ 库。我可以从 iOS 模拟器运行它的代码,所以我相信它是正确构建的。
  • 我有 Xcode 创建的骨架 iOS 应用程序

我想将日志记录添加到 C++ 库。我有一个采用fmt, ... 的trace() 方法。我使用-x Objective-c++编译那个.cpp,代码如下:

void trace (const char* sFmt, ...)
{
    va_list args;
    va_start(args, sFmt);

    NSString* sFmt2 = [ NSString stringWithUTF8String: sFmt ];
    NSLogv(sFmt2, args);

    va_end(args);
}

库编译得很好。但是,当我尝试链接应用程序时,出现链接器错误:

  ".objc_class_name_NSString", referenced from: literal-pointer@__OBJC@__cls_refs@NSString in lib.a(trace.o)

这很奇怪,因为我可以在项目本身的 .mm 文件中使用 NSString 和 NSLog。 Foundation 框架是链接的。此外,只是为了测试,我没有从我的库中调用 NSString,而是在项目中的 .mm 中添加了一个帮助器 foobar(),它会这样做

void foobar (const char* sFmt)
{
    NSLog([NSString stringWithUTF8String:sFmt]);
}

当从上面的库函数中调用它时,它可以工作!

我读到的关于这种错误的所有内容都涉及“刚刚更新了我的 SDK”的场景,这不是我的情况。两天前我开始做 iOS 的东西,我没有更改默认项目设置等。

我的猜测是名称修饰在某些时候失败了,因为我知道 NSString 确实是链接的,但似乎库引用的名称与链接的名称不同。

有什么想法吗?

【问题讨论】:

    标签: c++ objective-c xcode


    【解决方案1】:

    您的链接器输出表明您的命令行构建库是 lib.a,这表明它是一个静态库。我猜想,不是 dylib,它不知道如何使用 dyloader 在运行时查找丢失的符号。与此相关,我怀疑 iOS 项目将动态链接到这些系统库中(即使非操作系统开发人员无法创建动态框架),而您的静态 C++ 库将期望在链接时解析这些符号。

    我怀疑这三件事中的任何一个都可以解决这个问题:(按吸引力降序排列)

    1. 在构建 C++ 库时静态链接到正确的库
    2. 使 C++ 库成为 dylib 而不是静态库(因此它会期望在运行时使用 dyloader 找到丢失的符号)
    3. 静态链接您的整个应用程序(因此 NSString 类符号在应用程序链接时出现)(这是一个坏主意,如果它甚至可能的话,但可能会解决问题。)

    希望这会有所帮助!

    【讨论】:

    • 感谢您的建议。我的印象是 iOS 不支持 dylib。我试试看!
    • 啊,是的。我认为这是不允许的动态链接 frameworks 但我检查了它似乎是所有非操作系统动态库,其中自然包括所有动态链接框架。无论如何,我想这取决于选项 #1 或 #3。
    【解决方案2】:

    我能够通过使用libtool 而不是ld、将其传递-framework Foundation 并将-fobjc-abi-version=2 传递给gcc 来解决此问题。

    【讨论】:

    • 我相信这相当于我的回答中的建议#1。
    • @ipmcc:不是真的。产生差异的开关是 -fobjc-abi-version=2。我相信 -framework Foundation 在那里是多余的,因为 libtool 在制作静态库时实际上并没有进行任何类型的链接。选择 ABI 版本的开关与我的问题完全一致,从一开始就看起来像是名称修改问题。
    • 酷!感谢您的澄清。很高兴知道。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多