1

我正在尝试将 Dropbox Sync API (v1.1.2) 添加到使用 Marmalade (v6.3) 构建的 iOS 应用程序中。我收到以下链接错误:

Undefined symbols for architecture armv7:
"___udivmodsi4", referenced from:
_sqlite3BitvecSet in libDropbox.a(sqlite3.o)
_sqlite3BitvecClear in libDropbox.a(sqlite3.o)
_sqlite3BitvecTest in libDropbox.a(sqlite3.o)
ld: symbol(s) not found for architecture armv7

谷歌搜索该错误消息的相关部分会发现某个 SQLCipher 库的许多用户遇到相同的问题,并建议该问题是由用于构建该库的编译器和使用它的各种项目的不一致引起的。

由于我们项目的构建系统是由 Marmalade 工具集设置的,因此我认为更改编译器(我相信目前是 Marmalade 提供的 GCC 4.4 版本)不是一种选择。

谁能更准确地告诉我出了什么问题?这个问题还有其他解决方法吗?

4

2 回答 2

2

在像 ARM 这样具有相对简单指令集的处理器上,一些更复杂的操作被映射到函数调用而不是指令序列。当您使用“正确的”编译器进行链接时,它们的实现会被引入并且它可以工作!你通常不会看到它。

显而易见的解决方案是使用 marmalade 来编译 Dropbox 库,然后它将使用兼容的编译器。

那么问题来了,我想,你是否有理由不这样做呢?当前的 Marmalade 编译器不支持 ARC。我想这将是不在 ARC 下编译的原因。

于 2013-09-26T06:54:02.370 回答
1

另一个答案是正确的。但是,对于这个特定问题(如果这些是您遇到的唯一链接器错误),我看到了两种解决方法:

  1. 从 sqlite3 获取源代码,其中包含sqlite3BitvecSet并在您自己的项目中编译这些函数以覆盖库。他们将获取您自己的编译器提供的任何 divmod 支持。
  2. 实现你自己的udivmodsi4. 您不必实现按位除法(尽管您可以从 GCC 源代码中获取基本的 C 实现)。您只需在本机操作中实现它并让您的编译器调用它需要的任何内部支持。

这是未经测试的,但应该给你基本的想法。您可能需要在名称上添加更多下划线以匹配其他构建环境的行为/命名:

unsigned long
udivmodsi4(unsigned long num, unsigned long den, int modwanted)
{
    if (modwanted)
        return num % den;
    else
        return num / den;
}
于 2013-09-30T17:20:58.720 回答