0
在Windows平臺上,可能會創建一個圍繞可能從非託管代碼使用的託管對象的COM包裝。是否有可能從Xamarin中的C調用託管方法.IOS
因爲我只是在處理一個問題,我想從託管代碼傳遞託管System.IO.Stream引用到遺留的C庫函數(它甚至沒有Objective-C),我很好奇如果有什麼機會可以完成這個工作?
在Windows平臺上,可能會創建一個圍繞可能從非託管代碼使用的託管對象的COM包裝。是否有可能從Xamarin中的C調用託管方法.IOS
因爲我只是在處理一個問題,我想從託管代碼傳遞託管System.IO.Stream引用到遺留的C庫函數(它甚至沒有Objective-C),我很好奇如果有什麼機會可以完成這個工作?
不,您不能將這樣的託管參考傳遞給iOS中的C代碼。
但是你可以做反向P/Invoke調用:你給本地代碼一個委託,並且你可以從C調用這個委託作爲函數指針。
下面是一些(未經測試)的示例代碼,應該讓你在正確的軌道上:
delegate long GetLengthCallback (IntPtr handle);
// Xamarin.iOS needs to the MonoPInvokeCallback attribute
// so that the AOT compiler can emit a method
// that can be called directly from native code.
[MonoPInvokeCallback (typeof (GetLengthCallback)]
static long GetLengthFromStream (IntPtr handle)
{
var stream = (Stream) GCHandle.FromIntPtr (handle).Target;
return stream.Length;
}
static List<object> delegates = new List<object>();
static void SetCallbacks (Stream stream)
{
NativeMethods.SetStreamObject (new GCHandle (stream).ToIntPtr());
var delGetLength = new GetLengthCallback (GetLengthFromStream);
// This is required so that the GC doesn't free the delegate
delegates.Add (delGetLength);
NativeMethods.SetStreamGetLengthCallback (delGetLength);
// ...
}
優秀的信息! –
還有一個問題。如果非託管代碼將爲較小的數據塊頻繁調用Stream.Read委託_very_,那麼非託管到託管轉換的影響會有多嚴重? –
每一次轉換都會產生重大影響,但是如果您關心這種影響或者不是真的取決於您的應用程序。我的猜測是,除非每秒鐘調用數千次,否則你不會注意太多,但是你需要進行測量以確保。我首先會選擇簡單的方法,如果在分析後發現問題,則可以通過在本機代碼中添加一些簡單的緩衝來輕鬆改進它。 –