2013-08-17 40 views
0

在Windows平臺上,可能會創建一個圍繞可能從非託管代碼使用的託管對象的COM包裝。是否有可能從Xamarin中的C調用託管方法.IOS

因爲我只是在處理一個問題,我想從託管代碼傳遞託管System.IO.Stream引用到遺留的C庫函數(它甚至沒有Objective-C),我很好奇如果有什麼機會可以完成這個工作?

回答

3

不,您不能將這樣的託管參考傳遞給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); 
    // ... 
} 
+0

優秀的信息! –

+0

還有一個問題。如果非託管代碼將爲較小的數據塊頻繁調用Stream.Read委託_very_,那麼非託管到託管轉換的影響會有多嚴重? –

+0

每一次轉換都會產生重大影響,但是如果您關心這種影響或者不是真的取決於您的應用程序。我的猜測是,除非每秒鐘調用數千次,否則你不會注意太多,但是你需要進行測量以確保。我首先會選擇簡單的方法,如果在分析後發現問題,則可以通過在本機代碼中添加一些簡單的緩衝來輕鬆改進它。 –

相關問題