2013-12-20 88 views
2

這是我的C++代碼:
這個函數被導出到我的DLL中。如何掛鉤託管函數內的非託管函數?

EXPORT set_hook(fnc_public_hook hook){ 
    public_hook = hook; 
} 

現在,如果我從非託管代碼把它掛像下面的一切工作正常。

set_hook(my_fnc); 

現在被稱爲在我的DLL my_fnc每一個事件之前,所以我可以做一些數據預處理中。

問題是我不知道如何在.NET中做到這一點。
如何獲取.NET函數指針?如何在每個事件之前使用set_hook()來調用我的.NET函數?

+1

只需使用'Marshal.GetFunctionPointerForDelegate'。但是請注意,儘管您需要保留對委託的參考,否則它將收集垃圾。 – Luaan

+0

@Luaan我想你誤會了我。不僅我想發送我的.NET函數指針,我希望C++調用我的.NET函數。 –

+2

您誤解了Luaan,只要您調用public_hook(),您的C++代碼將*調用.NET代碼。 –

回答

0
using System.Runtime.InteropServices; 

某處,創建委託給你的函數,你想叫

[UnmanagedFunctionPointer(CallingConvention.Cdecl)] 
internal delegate uint YourFunctionDelegate(); 

設置您的代理指向你的函數,即在你的構造,

YourFunctionDelegate = myDotNetFunc; 

在NativeMethods類在你的名字空間內,

[DllImport("YourDLL.dll", EntryPoint = "set_hook", CallingConvention = CallingConvention.Cdecl)] 
    private static extern int setHook([MarshalAs(UnmanagedType.FunctionPtr)]YourFunctionDelegate myDelegate); 

最後,你可以打電話給你的C++函數

NativeMethods.setHook(YourFunctionDelegate); 

確保你知道哪些調用約定是合適的。

編輯:不要垃圾收集!

http://msdn.microsoft.com/en-us/library/ms182294%28v=vs.80%29.aspx

Preventing unmanaged function pointer garbage collection

+1

需要注意的一件事是,如果你有一個「我帶着委託調用C的模型,在返回之前,委託被調用」的模型,你的狀態很好,你的代碼將是可靠的。如果模型是「我用委託調用C,它會返回,然後我花了很多時間調用C,然後調用我的委託」,您可能會遇到問題。根據我的經驗,CLR最終會把你的代表和它的非託管垃圾垃圾扔進大學。 – plinth

+0

你是對的。我從工作中拉出一個項目,忘記提及我正在使用SafeHandle。 – RW4

相關問題