C ++ / ObjC中的链接器问题

时间:2011-04-01 13:35:53

标签: c++ objective-c xcode

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

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

我想将日志记录添加到C ++库中。我有一个trace()方法,它采用fmt, ...。我使用-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。基金会框架是相互关联的。而且,只是为了测试,而不是从我的库中调用NSString,我在项目的.mm中添加了一个帮助器foobar(),这样做

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

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

我读到的关于此类错误的所有内容都涉及“刚更新的我的SDK”方案,这不是我的情况。两天前,我开始在字面上开始做iOS,我没有改变默认的项目设置等等。

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

有什么想法吗?

2 个答案:

答案 0 :(得分:0)

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

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

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

答案 1 :(得分:0)

我可以使用libtool代替ld,传递-framework Foundation并将-fobjc-abi-version=2传递给gcc来解决此问题。