Unity 和 Objective-C 交互 Unity 调用 iOS 原生方法 在 iOS 中,C 语言可以和 Objective-C 语言进行混合编译的,C# 语言又提供了一种调用 C(非 C++)语言的机制, 这样就可以实现 C# 调用 Objective-C 的功能
IL2CPP
What is IL2CPP? The technology that we refer to as IL2CPP has two distinct parts. 1. An ahead-of-time (AOT) compiler 2. A runtime library to support the virtual machine The AOT compiler translates Intermediate Language (IL), the low-level output from .NET compilers, to C++ source code. The runtime library provides services and abstractions like a garbage collector, platform-independent access to threads and files, and implementations of internal calls (native code which modifies managed data structures directly).
Unity脚本编译成中间语言(IL,动态库等),通过IL2CPP程序将 IL 转换成 C++语言
DllImport C# 提供了 DllImport 机制来实现 C# 于 C 语言的方法调用
1 2 [DllImport("__Internal" ) ] internal static extern void CallFunction () ;
1 2 [DllImport("__Internal" ) ] internal static extern void CallFunction (string param ) ;
1 2 [DllImport("__Internal" ) ] internal static extern string CallFunction (string param ) ;
DllImport 的语法规则 1 2 [DllImport("__Internal" ) ] internal static extern ReturnValue FunctionName (string parameter1, int parameter2 ) ;
由于是 C 语言,支持的参数及其数据类型是非常有限的,诸如 int、float、double、char 等这类两种语言中都存在的基础数据类型,是可以实现直接映射的,但是 C# 中的 string 对应到 C 中,就是 char* 了
iOS 实现 DllImport .h 文件中
1 2 3 extern "C" { char * CallFunction(char *parma); }
.mm 文件中
1 2 3 char * CallFunction(char *parma) { }
iOS 调用 Unity 原生方法 这种方式用于 iOS 给 Unity 一些方法回调
Attribute used to annotate functions that will be called back from the unmanaged world.
举个栗子🌰,比如我们现在需要使用手机相册权限拿一张图片在 Unity 中使用
C# 中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 private static UnityAction<string > _selectPhotoAction;private delegate void SelectPhotoCallback (string photo ) ;public void Init () { _SetSelectPhotoCallback(DidReceiveSelectPhotoCallback); } public void OnSelectPhoto (UnityAction<string > callback ){ _selectPhotoAction = callback; _SelectPhoto(); } [AOT.MonoPInvokeCallback(typeof(SelectPhotoCallback)) ] private static void DidReceiveSelectPhotoCallback (string photo ){ _selectPhotoAction?.Invoke(photo); } [DllImport("__Internal" ) ] private static extern void _SetupSelectPhotoCallback(SelectPhotoCallback callback);[DllImport("__Internal" ) ] private static extern void _SelectPhoto();
OC 中
.h 文件中:
1 2 3 4 5 6 7 8 9 @interface NativeUtils : NSObject typedef void (*SelectPhotoCallback)(const char *photo);extern "C" { void _SetupSelectPhotoCallback(SelectPhotoCallback callback); void _SelectPhoto(); } @end
.mm 文件中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 #define Convert2Char( _x_ ) ( _x_ != NULL && [_x_ isKindOfClass:[NSString class]] ) ? strdup( [_x_ UTF8String] ) : strdup( [@"" UTF8String] ) @interface NativeUtils ()@property (nonatomic , assign ) SelectPhotoCallback selectPhotoCallback;@end @implementation WMNativeUtils + (instancetype )shared { static dispatch_once_t onceToken; static NativeUtils *instance = nil ; dispatch_once (&onceToken,^{ instance = [[self alloc] init]; }); return instance; } - (void )bindSelectPhotoCallback:(SelectPhotoCallback)callback { self .selectPhotoCallback = callback; } - (void )selectPhoto { } #pragma mark UIImagePickerControllerDelegate - (void )imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary <UIImagePickerControllerInfoKey ,id > *)info { [picker dismissViewControllerAnimated:YES completion:nil ]; UIImage *image = info[UIImagePickerControllerEditedImage ]; NSString *imageBase64String = [imageData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed ]; if (self .selectPhotoCallback) { self .selectPhotoCallback(Convert2Char(imageBase64String)); } } #pragma mark - CPlusPlus void _SetupSelectPhotoCallback(SelectPhotoCallback callback) { [[NativeUtils shared] bindSelectPhotoCallback:callback]; } void _SelectPhoto() { [[NativeUtils shared] selectPhoto]; } @end