微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用嵌入式 Mono 将本机 Objective-C 对象指针传递给 Xamarin iOS 包装器对象

如何解决如何使用嵌入式 Mono 将本机 Objective-C 对象指针传递给 Xamarin iOS 包装器对象

我有以下设置:

Xcode 中的 Obj-C iOS 应用程序,它嵌入了 Mono,并且能够使用 mono_runtime_invoke 从 C# DLL 调用方法。我能够将简单的数据类型作为方法参数传递——比如整数、字符串、数据数组——并在托管 C# 端轻松使用它们。

我现在正在尝试传递 Obj-C 对象指针 - 为简单起见,假设它是 NSObject - 并使用以下内容在托管端创建 Xamarin.iOS NSObject 包装器:

NSObject nSObject = ObjCRuntime.Runtime.GetNSObject(intPtr);
NSObject nSObject = ObjCRuntime.Runtime.GetINativeObject<NSObject>(intPtr,false);
NSObject nSObject = ObjCRuntime.Runtime.TryGetNSObject(intPtr);

在本机 iOS 端,我尝试使用以下结构传递指向对象的指针:

void* args [1];
NSObject *test = [[NSObject alloc] init];  
args[0] = (__bridge void*) test;
...
result = mono_runtime_invoke(method,object,args,NULL);

并在托管端调用它:

public void Test(IntPtr intPtr)
{
    Console.WriteLine("Test");
    Console.WriteLine(intPtr);

    NSObject nSObject = new NSObject(intPtr,false);
    NSObject nSObject = ObjCRuntime.Runtime..GetNSObject(intPtr);
    NSObject nSObject = ObjCRuntime.Runtime.GetINativeObject<NSObject>(intPtr,false);   
}

public unsafe void Test(void * ptr)
{
    Console.WriteLine("Test");
    IntPtr intPtr = new IntPtr(ptr);
    Console.WriteLine(intPtr);

    NSObject nSObject = new NSObject(intPtr,false);   
}

但这一切都失败了,例外情况类似于:

2021-03-14 23:12:23.566762+0100 MonoDeviceApp[22980:2028166] 
Unhandled Exception:
System.ArgumentNullException: Value cannot be null.
Parameter name: obj
  at (wrapper managed-to-native) System.Object.__icall_wrapper_mono_monitor_enter_v4_internal(object,intptr)
  at ObjCRuntime.Runtime.TryGetNSObject (system.intPtr ptr,System.Boolean evenInFinalizerQueue) <0x101c69740 + 0x00067> in <ad1be307855442e4b2cb88e33f94f908>:0 
  at ObjCRuntime.Runtime.TryGetNSObject (system.intPtr ptr) <0x101c69710 + 0x00017> in <ad1be307855442e4b2cb88e33f94f908>:0 
  at MyLib.Test (system.intPtr intPtr) <0x10328ec30 + 0x00047> in <7012236733d14cc49ecd2b0a562adc75>:0
2021-03-14 23:12:23.566964+0100 MonoDeviceApp[22980:2028166] mono-rt: [ERROR] FATAL UNHANDLED EXCEPTION: System.ArgumentNullException: Value cannot be null.
Parameter name: obj
  at (wrapper managed-to-native) System.Object.__icall_wrapper_mono_monitor_enter_v4_internal(object,System.Boolean evenInFinalizerQueue) <0x101c69740 + 0x00067> in <ad1be307855442e4b2cb88e33f94f908>:0 
  at ObjCRuntime.Runtime.TryGetNSObject (system.intPtr ptr) <0x101c69710 + 0x00017> in <ad1be307855442e4b2cb88e33f94f908>:0 
  at MyLib.Test (system.intPtr intPtr) <0x10328ec30 + 0x00047> in <7012236733d14cc49ecd2b0a562adc75>:0
2021-03-14 23:12:23.567010+0100 MonoDeviceApp[22980:2028166] Terminating runtime due to unhandled exception

我也尝试使用 mono_value_Box 将指针装箱,但也失败了。

问题是 - 它会起作用以及如何更改上述代码概念以使其起作用。可能与内存管理有关,因此我首先需要在托管端为本机对象分配内存,反之亦然。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。