- objective-c - iOS 5 : Can you override UIAppearance customisations in specific classes?
- iphone - 如何将 CGFontRef 转换为 UIFont?
- ios - 以编程方式关闭标记的信息窗口 google maps iOS
- ios - Xcode 5 - 尝试验证存档时出现 "No application records were found"
以前有人问过这个问题,但深入研究各种开发工具的文档似乎是可能的,只是不明显。
动机: 制作供其他 iOS 开发人员使用的静态库。库中的某些符号如果导出会导致问题,因此我希望将它们设为仅供内部使用的符号。使用动态库这很容易,只需使用 -exported_symbols_list
libtool
(ld
) 参数并列出您想要公开的那些。 libtool
文档不允许对静态库使用此参数。
库有几个 ObjectiveC .m 文件,它们相互使用代码。组中只有一个类需要公开给最终.a 静态库文件的用户。
尝试了 libtool -exported_symbols_list publicsymbols.exp
但是 libtool
的参数不支持静态库的 -static
。
不能使用属性将符号设置为私有(private)(如果这样可行的话),因为组中的其他 .m 文件需要它们。
看起来 ld
可以获取多个 .o 文件并将它们链接在一起成为一个新的 .o 文件(通过 -r
参数)并且它没有-exported_symbols_list
参数的“仅限动态”免责声明(可能只是文档不清楚...)。
作为测试,我使用 Xcode 构建了我的项目,因此我制作了所有 .o 文件,然后尝试在命令行上调用 ld
,如下所示:
ld -r -x -all_load -static -arch armv6 -syslibroot {path}
-filelist /Users/Dad/ABCsdk/iphone-ABClib/build/ABCLib.build/Distribution-iphoneos/ABCLib-device.build/Objects-normal/armv6/ABCsdk.LinkFileList
-exported_symbols_list {exp file path} -o outputfile.o
{path} 类型的东西有通往那里适当位置的长路径。
但我收到如下错误:
/usr/bin/ld_classic: /Users/Dad/ABCsdk/iphone-ABClib/build/ABCLib.build/Distribution-iphoneos/ABCLib-device.build/Objects-normal/armv6/ABCmain.o incompatible, file contains unsupported type of section 3 (_TEXT,_picsymbolstub4) in load command 0 (must specify "-dynamic" to be used)
所以那里似乎有问题......
有谁知道使这项工作有效的巧妙方法吗?谢谢。
最佳答案
这真的不可能,我很抱歉。它与静态库的工作方式有关。静态库只不过是一堆捆绑在一起的目标 *.o
文件,而动态库是一个可加载的二进制镜像,就像可执行文件一样。
假设你有四个文件,
common
,也就是“private”fn1
,调用common
。fn2
,调用common
。other
。在动态库中,链接器将所有内容打包成一大块代码。该库导出 other
、fn1
和 fn2
。您必须加载整个库或一个都不加载,但是两个程序都可以加载它而无需在内存中放置多个副本。 common
的入口点只是从符号表中丢失了 — 您不能从库外部调用它,因为链接器找不到它。
请注意,应用程序和共享库具有本质上相同的格式:应用程序基本上是一个仅导出一个符号 main
的共享库。 (这不完全正确,但接近。)
在静态库中,链接器从不运行。这些文件都被编译成 *.o 文件并放入 *.a 库存档中。内部引用将无法解析。
假设您的应用程序调用 fn1
。链接器看到对 fn1
的未解析调用,然后查看库。它在 fn1.o 中找到 fn1
的定义。然后链接器注意到对 common
的未解析调用,因此它在 common.o 中查找它。该程序不会从 fn2.c 或 other.c 中获取代码,因为它不使用这些文件中的定义。
静态库非常古老,不具备动态库的任何特性。您可以将静态库基本上看作是一个充满已编译源代码的 zip 文件,这与链接在一起的动态库不同。没有人费心去扩展存档格式来增加符号的可见性。当您链接静态库时,您会得到与将该库的源代码添加到您的程序中相同的结果。
简短版本:动态库有一个包含所有导出符号的符号表,但没有私有(private)符号。同样,一个目标文件有一个包含所有 extern
符号的列表,但没有一个 static
符号。但是静态库没有符号表,它只是一个存档。因此,没有任何机制可以使代码对静态库私有(private)(除了定义对象 static
之外,但这不适用于 Objective-C 类)。
如果我们知道您尝试这样做的原因,也许我们可以给您一个建议。 (是为了安全?名字冲突?所有这些问题都有解决方案。)
关于objective-c - 如何在不公开所有符号的情况下为 iOS 创建静态库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6894214/
我是 Java 新手,这是我的代码, if( a.name == b.name && a.displayname == b.displayname && a.linknam
在下面的场景中,我有一个 bool 值。根据结果,我调用完全相同的函数,唯一的区别是参数的数量。 var myBoolean = ... if (myBoolean) { retrieve
我是一名研究 C++ 的 C 开发人员: 我是否正确理解如果我抛出异常然后堆栈将展开直到找到第一个异常处理程序?是否可以在不展开的情况下在任何 throw 上打开调试器(即不离开声明它的范围或任何更高
在修复庞大代码库中的错误时,我观察到一个奇怪的情况,其中引用的动态类型从原始 Derived 类型更改为 Base 类型!我提供了最少的代码来解释问题: struct Base { // some
我正在尝试用 C# 扩展给定的代码,但由于缺乏编程经验,我有点陷入困境。 使用 Visual Studio 社区,我尝试通过控制台读出 CPU 核心温度。该代码使用开关/外壳来查找传感器的特定名称(即
这可能是一个哲学问题。 假设您正在向页面发出 AJAX 请求(这是使用 Prototype): new Ajax.Request('target.asp', { method:"post", pa
我有以下 HTML 代码,我无法在所有浏览器中正常工作: 我试图在移动到
我对 Swift 很陌生。我如何从 addPin 函数中检索注释并能够在我的 addLocation 操作 (buttonPressed) 中使用它。我正在尝试使用压力触摸在 map 上添加图钉,在两
我设置了一个详细 View ,我是否有几个 Nib 文件根据在 Root View Controller 的表中选择的项目来加载。 我发现,对于 Nibs 的类,永远不会调用 viewDidUnloa
我需要动态访问 json 文件并使用以下代码。在本例中,“bpicsel”和“temp”是变量。最终结果类似于“data[0].extit1” var title="data["+bpicsel+"]
我需要使用第三方 WCF 服务。我已经在我的证书存储中配置了所需的证书,但是在调用 WCF 服务时出现以下异常。 向 https://XXXX.com/AHSharedServices/Custome
在几个 SO 答案(1、2)中,建议如果存在冲突则不应触发 INSERT 触发器,ON CONFLICT DO NOTHING 在触发语句中。也许我理解错了,但在我的实验中似乎并非如此。 这是我的 S
如果进行修改,则会给出org.hibernate.NonUniqueObjectException。在我的 BidderBO 类(class)中 @Override @Transactional(pr
我使用 indexOf() 方法来精细地查找数组中的对象。 直到此刻我查了一些资料,发现代码应该无法正常工作。 我在reducer中尝试了上面的代码,它成功了 let tmp = state.find
假设我有以下表格: CREATE TABLE Game ( GameID INT UNSIGNED NOT NULL, GameType TINYINT UNSIGNED NOT NU
代码: Alamofire.request(URL(string: imageUrl)!).downloadProgress(closure: { (progress) in
我是一名优秀的程序员,十分优秀!