我將不勝感激,幫助解決一個問題,我一直堅持了幾天。C#pInvoke到一個C函數
我有一個本地C++函數類型中聲明這樣:
typedef STATUS (T_TED_AcppBoxDYN_RegisterEventCallback) (
PEventCallback function, // pointer to the customer callback
PVOID param // custom data (returned in callback)
);
其中PEventCallback
和PEVENT
聲明像這樣:
typedef int (*PEventCallback) (PEVENT event, PVOID param);
typedef struct
{
int nEventId;
void* pParam;
} EVENT,*PEVENT;
的C++代碼提供一個指針作爲該類型的功能一個全局變量:
T_TED_AcppBoxDYN_RegisterEventCallback* TED_AcppBoxDYN_RegisterEventCallback
= NULL;
這是init稍後通過此代碼ialized:
#ifdef LOAD_PROC_ADDRESS
#undef LOAD_PROC_ADDRESS
#endif
#define LOAD_PROC_ADDRESS(handle,func) \
if((func=(T_##func*)GetProcAddress(handle,#func))==NULL) \
{\
sMsg.Format("Error occurs while loading entry point\n'%s'\n"\
"from detector DLL '%s'\n", GetName(), #func);\
MessageBox(NULL, sMsg.GetBuffer(), "Load Proc Error", MB_OK | MB_ICONSTOP);\
return (false);\
}
bool P5100EDllManager::LoadProc()
{
CString sMsg;
HMODULE hDllHandle = GetHandle();
if (hDllHandle == NULL)
{
return false; // cannot load the proc if the dll has not been loaded
}
LOAD_PROC_ADDRESS(hDllHandle, TED_AcppBoxDYN_RegisterEventCallback);
return true;
}
我想調用C#中的指向函數。爲此,我已經定義了一個C#包裝:
public delegate void TDICallBack(IntPtr callbackEvent, IntPtr pParam);
[DllImport(DLL, EntryPoint = "TED_AcppBoxDYN_RegisterEventCallback", CallingConvention = CallingConvention.Cdecl)]
private static extern int TED_AcppBoxDYN_RegisterEventCallback(TDICallBack callBack, IntPtr param);
public void RegisterEventCallback(TDICallBack callBack, IntPtr param)
{
TED_AcppBoxDYN_RegisterEventCallback(callBack, param);
}
我使用它是這樣的:
TdiapiFacade.RegisterEventCallback(OnTdiCallBack, IntPtr.Zero);
public void OnTdiCallBack(IntPtr ptr, IntPtr param)
{
}
的RegisterEventCallback()
似乎順利進行,但在回調函數應該點被調用,應用程序崩潰。正如你所看到的,在這個階段,我甚至沒有解開提供給回調函數的參數。
我需要做些什麼來完成這項工作?
與您的斷言相反,C代碼不聲明任何函數。如果它是有效的C(這對我和CDECL來說似乎很懷疑),那麼它將'T_TED_AcppBoxDYN_RegisterEventCallback'聲明爲一個*別名*,用於函數*類型*。也許它是有效的C++,但即使在這種情況下,它也必須聲明一個類型別名,而不是該類型的實際函數或函數指針。 – 2014-12-05 16:29:11
如何定義'STATUS'? – Dennis 2014-12-05 16:47:10
您不能直接從C#調用非託管C++實例函數。因爲你沒有'this'指針。另外,你的'TDICallback'委託必須是Cdecl。你需要'[UnmanagedFunctionPointer(CallingConvention.Cdecl)]'屬性。請參閱http://stackoverflow.com/questions/5155180/changing-a-c-sharp-delegates-calling-convention-to-cdecl – 2014-12-05 16:50:10