2013-12-08 46 views
3

使用.calli IL-指令從.NET調用C++對象的方法時,如何解析指向您想要的實際方法的指針呼叫?我意識到這將取決於平臺。如何使用OpCodes調用指向C++對象的指針方法.Calli

我知道的優秀SharpDX庫使用.calli指令廣泛,我在它生成的代碼已經偷看和方法指針被拉出這樣的:

((void**)(*(void**)_nativePointer))[69] 

其中_nativePointer是一個指向對象實例。然後將它轉換爲一個void **,這是一個引用,然後再次投射到一個無效**,該索引插入到槽69中。我只是無法弄清楚這裏究竟發生了什麼。

+4

SharpDX並不是一個很好的例子,它調用了DirectX。它使用COM接口,你可能會看到它從v表中挖掘函數指針。理解COM如何工作遠遠超出了可能適用於SO答案的內容。關於它的很多書籍。 –

回答

2

Calli操作碼只適用於具有vtable的對象,但不能用於標準C++方法(非虛擬)。它還要求對象遵循相同的ABI,因此它與COM協同工作,因爲它定義了一個標準的ABI來訪問C++對象。但是,這對於例如C++多繼承無效。

爲了訪問對象上的純C++方法,您需要生成一個生成的C封裝器,爲每個C++方法提供一個純C函數,其中第一個參數通常是C++對象的實例,並且以下參數是來自C++方法的參數(像CXXI那樣的一些包裝器有時能夠通過跟隨編譯器ABI直接鏈接到C++對象)。因此,爲了使這個橋樑,您可以:

  • 開發自己的C包裝(A DLL動態庫/所以這是提供這些功能轉換調用C++對象)
  • SWIG通常用於自動化這種的C++/C#橋。
  • 也有一些Mono人嘗試提供稱爲CXXI的C++橋接,但似乎沒有開發出來。
+0

儘管它不是我想要的答案,但這是正確的答案=(。謝謝! – thr

+0

那麼'calli'如何用於調用純C函數?如何獲取地址? 'LoadLibrary'/'GetProcAddress'? – nietras

+0

'calli'允許調用任何本地函數,最後一個推送給calli指令的參數就是這個函數的指針。對於COM對象的方法,這個指針來自於vtable槽關聯到這個方法對於一個導出的DLL函數,這確實是'LoadLibrary/GetProcessAddress' – xoofx

相關問題