本页介绍如何构建适用于 iOS 平台的原生代码插件。
要构建适用于 iOS 且包含原生插件的应用程序,请遵循以下步骤:
对于要调用的每个原生函数,在 C# 文件中定义一个 extern 方法,如下所示:
[DllImport ("__Internal")]
private static extern float FooPluginFunction();
将原生代码源文件添加到 Unity 项目中。
在 Plugin Inspector 窗口中自定义插件的设置。例如,如果原生代码是特定于 iOS,请确保仅为 iOS 启用该插件。
注意:如果使用 C++ (.cpp) 或 Objective-C++ (.mm) 来实现该插件,则必须使用 C 链接来声明函数以免发生名称错用问题:
extern "C" {
float FooPluginFunction();
}
用 C 或 Objective-C 编写的插件不需要此声明,因为这些语言不存在名称错用。
仅当 iOS 原生插件部署在了实际设备上时,您的应用程序才能调用这些插件,因此应该使用额外的 C# 代码层来封装所有原生代码方法。此代码应使用 UNITY_IOS && !UNITY_EDITOR
条件编译,或者检查 Application.platform
,并仅当应用程序在设备上运行时才调用原生方法。最简单的实现方式是:
void MyMethod()
{
# if UNITY_IOS && !UNITY_EDITOR
CallNativeMethodImplementation();
# else
CallEditorMethodImplementation();
# endif
}
For a more detailed implementation, download the Bonjour Browser sample below.
Unity iOS 支持有限的原生到托管回调功能。有两种方式可以做到这一点:
UnitySendMessage
UnitySendMessage
此选项更简单,但有一些限制。如下所示:
UnitySendMessage("GameObjectName1", "MethodName1", "Message to send");
有三个参数:
GameObject
的名称使用 UnitySendMessage
时具有以下限制:
void MethodName(string message);
。UnitySendMessage
的调用是异步的,并有一帧延迟。UnitySendMessage
.这是更复杂的方案。当使用委托时,C# 端的方法必须是静态的,并且必须用 MonoPInvokeCallback
属性进行标记。必须将该方法作为委托传递给在原生代码中作为函数实现的 extern 方法,这个函数采用一个指针,而指针则指向具有对应签名的函数。然后,原生代码中的函数指针再引回 C# 静态方法。
该方法的 C# 代码如下所示:
delegate void MyFuncType();
[AOT.MonoPInvokeCallback(typeof(MyFuncType))]
static void MyFunction() { }
static extern void RegisterCallback(MyFuncType func);
然后,接受回调的 C 代码如下所示:
typedef void (*MyFuncType)();
void RegisterCallback(MyFuncType func) {}
Unity supports automated plug-in integration and copies all files with the following extensions to the generated Xcode project if you enable them for iOS in the Plugin Inspector window: .a
, .m
, .mm
, .c
, .cpp
, .h
. If any files with these extensions are located in the Assets/Plugins/iOS
folder, Unity only enables them for the iOS platform.
注意:将文件复制到生成的 Xcode 项目后,它们不再链接到 Unity 项目中的对应文件。如果在 Xcode 中更改了这些文件,必须将它们复制回到您的 Unity 项目中。否则,在下次构建项目时,Unity 将覆盖它们。
在 iOS 上,托管到非托管的调用是很耗资源的处理器密集型操作。尽量避免每帧调用多个原生方法。
应使用额外的 C# 层来封装原生方法,该层将调用设备上的原生代码并在 Editor 中返回虚拟值。
从原生方法返回的字符串值应该是 UTF–8 编码并在堆上分配。Mono 编组调用对于这样的字符串是无成本的。
可在下面下载一个演示如何使用原生代码插件的简单示例:Bonjour 浏览器示例。
This example demonstrates how you can invoke Objective-C code from a Unity iOS application. This application implements a simple Bonjour client and consists of:
Plugins\Bonjour.cs
是原生代码的 C# 接口,BonjourTest.cs
是实现应用程序逻辑的脚本Assets/Plugins/iOS
中),如上文自动插件集成部分所述,应将此代码添加到构建的 Xcode 项目中Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.