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