您可以为 iOS 构建动态库并在运行时加载它们吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4733847/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can you build dynamic libraries for iOS and load them at runtime?
提问by user510951
Are dynamic libraries supported on iOS (iPhone/iPad)?
iOS (iPhone/iPad) 是否支持动态库?
In Xcode, I tried to create a New project-> Framework & Library-> Cocoa Library (dynamic). In the project settings, I set the Base SDKto iOS device 4.1
and target to iOS4.1
, but it has a build error:
在 Xcode 中,我尝试创建一个New project-> Framework & Library-> Cocoa Library (dynamic)。在项目设置中,我将Base SDK设置为iOS device 4.1
和目标为iOS4.1
,但它有一个构建错误:
target specifies product type 'com.apple.product-type.library.dynamic', but there's no such product type for the 'iphonesimulator' platform".
目标指定产品类型“com.apple.product-type.library.dynamic”,但“iphonesimulator”平台没有这样的产品类型”。
The build i selected is Simulator -> Debug -> i386.
我选择的构建是Simulator -> Debug -> i386。
采纳答案by DarkDust
At the time this question was asked, Dynamic libraries were not supported by iOS and will result in your app getting rejected. Only static libraries are allowed.
在提出此问题时,iOS 不支持动态库,这将导致您的应用程序被拒绝。只允许使用静态库。
However, in iOS8 you can use dynamic libraries and frameworks. It should "just work"
但是,在 iOS8 中,您可以使用动态库和框架。它应该“正常工作”
回答by Nate
I'm not really disagreeing with DarkDust's answer, but if I may channel my inner Bill Clinton, it depends on what the meaning of supportedis:)
我并不是真的不同意DarkDust的答案,但如果我可以引导我内心的比尔·克林顿,要看是什么意思支持是:)
Apple doesn't want you doing this for App Store apps, but the operating system certainly allows it. Jailbreak apps use this technique all the time. You basically use a standard UNIX technique to dynamically open a framework/library, and then use stuff in it. The dlopen functionallows you to open the library by passing in the path to that framework, or dylib. From some docs for building jailbreak apps, here's an example of calling an init()
function implemented inside your own, separate dylib:
Apple 不希望您为 App Store 应用程序执行此操作,但操作系统当然允许这样做。越狱应用一直使用这种技术。您基本上使用标准的 UNIX 技术来动态打开框架/库,然后使用其中的内容。该dlopen的功能,您可以通过在传递给打开库的路径框架,或dylib。从一些用于构建越狱应用程序的文档中,这里有一个调用init()
在您自己的独立 dylib 中实现的函数的示例:
#include <dlfcn.h>
initWrapper() {
char *dylibPath = "/Applications/myapp.app/mydylib2.dylib";
void *libHandle = dlopen(dylibPath, RTLD_NOW);
if (libHandle != NULL) {
// This assumes your dylib's init function is called init,
// if not change the name in "".
void (*init)() = dlsym(libHandle, "init");
if (init != NULL) {
init();
}
dlclose(libHandle);
}
}
Furthermore, the default restriction against allowing you to builda dynamic library project for iOS is something in Xcode that you have the ability to override by editing some XCode xml files:
此外,不允许您为 iOS构建动态库项目的默认限制是 Xcode 中的某些内容,您可以通过编辑一些 XCode xml 文件来覆盖该限制:
Once you do this, you can build a normal iOS .dyliblibrary, and use it per the sample code above. (yes, you probably will have to unlock this capability again whenever you install a new XCode version).
完成此操作后,您可以构建一个普通的 iOS .dylib库,并按照上面的示例代码使用它。(是的,每当您安装新的 XCode 版本时,您可能都必须再次解锁此功能)。
So, it's not a technical limitation, but an App Store policy limitation. If you're not limited to the App Store, then you can do it. Note that this technique does notrequire jailbreaking, although if the app is sandboxed, it may limit wheredylibs can be loaded from.
因此,这不是技术限制,而是 App Store 政策限制。如果您不仅限于 App Store,那么您可以做到。请注意,这种技术并没有要求越狱,但如果应用程序是沙箱,它可以限制在那里dylibs可以被加载。
Edit:in order to make sure this information isn't lost to future link rot, here is the content of the link I provided on how to enable iOS dylibs in Xcode. (Note:this process still works on Xcode 4, but see comment(s) below for updates to paths, etc.) Source is the iOS Place blog:
编辑:为了确保此信息不会因将来的链接失效而丢失,这里是我提供的有关如何在 Xcode 中启用 iOS dylib 的链接的内容。(注意:此过程仍然适用于 Xcode 4,但请参阅下面的评论以获取路径更新等。)来源是iOS Place 博客:
Xcode does not allow you to build dylib for iOS. App will be rejected if it's not single binary. But I have an application that has plug-in architecture to load optional modules. I just want a quick prototype to prove concept before fully port it to iOS. It's faster to do if dylib could simply work. So, this post shows how to build and use dylib but be aware it won't be approved to App Store. (Tested with Xcode 3.2.4 on 10.6.4)
Xcode 不允许您为 iOS 构建 dylib。如果不是单个二进制文件,应用程序将被拒绝。但是我有一个具有插件架构的应用程序来加载可选模块。我只想要一个快速原型来证明概念,然后再将其完全移植到 iOS。如果 dylib 可以简单地工作,它会更快。所以,这篇文章展示了如何构建和使用 dylib,但要注意它不会被 App Store 批准。(在 10.6.4 上用 Xcode 3.2.4 测试)
1.Open these files in the Property List Editor: /Developer/Platforms/MacOSX.platform/Developer/Library/Xcode/Specifications/MacOSX Product Types.xcspecand /Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Specifications/iPhone Simulator ProductTypes.xcspec
1.在属性列表编辑器中打开这些文件:/Developer/Platforms/MacOSX.platform/Developer/Library/Xcode/Specifications/MacOSX Product Types.xcspec和/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Specifications /iPhone 模拟器 ProductTypes.xcspec
2.Locate the item in the “MacOSX Product Types.xcspec” that has the product type com.apple.product-type.library.dynamic
and drag it to the “iPhone Simulator ProductTypes.xcspec”.
2.在“ MacOSX Product Types.xcspec”中找到具有产品类型的项目com.apple.product-type.library.dynamic
并将其拖到“ iPhone Simulator ProductTypes.xcspec”中。
3.Open “MacOSX Package Types.xcspec” and “iPhone Simulator PackageTypes.xcspec” found at the same places.
3.打开“ MacOSX Package Types.xcspec”和“ iPhone Simulator PackageTypes.xcspec”在同一位置找到。
4.Locate the item in the “MacOSX Product Types.xcspec” that has the package type com.apple.package-type.mach-o-dylib
and drag it to the “iPhone Simulator PackageTypes.xcspec”.
4.在“ MacOSX Product Types.xcspec”中找到包含包类型的项目com.apple.package-type.mach-o-dylib
,将其拖到“ iPhone Simulator PackageTypes.xcspec”中。
5.Repeat the steps for the “iPhoneOS.platform” and relaunch Xcode if it was running.
5.对“ iPhoneOS.platform”重复这些步骤,如果它正在运行,则重新启动 Xcode。
Now, lets build a dylib. Start out with the “Cocoa Touch Static Library” Template. That should included the Foundation.framework in the project. Here are the changes I made on top of the template to build dylib.
现在,让我们构建一个 dylib。从“ Cocoa Touch 静态库”模板开始。这应该包括项目中的 Foundation.framework。以下是我在模板之上为构建 dylib 所做的更改。
1.Open the file project.pbxproj(found inside the Xcode project file bundle) in a Text Editor. Search for string “producttype”, change it's value to com.apple.product-type.library.dynamic
;
1.在文本编辑器中打开文件project.pbxproj(在 Xcode 项目文件包中)。搜索字符串“ producttype”,将其值更改为com.apple.product-type.library.dynamic
;
Now, open the project with Xcode, go to Project->Edit Project Settings
现在,使用 Xcode 打开项目,转到Project->Edit Project Settings
2.“Installation Directory” set to @executable_path/
because I plan to put the dylib in the same directory as the app's executable.
2.“安装目录”设置为@executable_path/
因为我打算将dylib与应用程序的可执行文件放在同一目录中。
3.“Mach-O Type” set to Dynamic Library
3.“ Mach-O Type”设置为动态库
4.“Executable Extension” set to dylib
4.“可执行扩展”设置为dylib
5.“Executable Prefix” set to empty
5.“ Executable Prefix”设置为空
6.Add one or two simple methods to the library and build it.
6.向库中添加一两个简单的方法并构建它。
Now, create an app to test it. This time, I choose the View-based Application. Hook up a UIButton and a UILabel to call the lib and showing return message. You can download the complete project TestAppand play with it.
现在,创建一个应用程序来测试它。这次,我选择了View-based Application。连接一个 UIButton 和一个 UILabel 来调用 lib 并显示返回消息。您可以下载完整的项目 TestApp并使用它。
回答by Carla Camargo
Starting from Xcode 11.4.1 dynamic libraries are not allowed (your project won't compile for all destinations). The new way to use libs/frameworks is the create-xcframework from xcodebuild.
不允许从 Xcode 11.4.1 开始动态库(您的项目不会为所有目标编译)。使用 libs/frameworks 的新方法是来自 xcodebuild 的 create-xcframework。