我将不胜感激,帮助解决一个问题,我一直坚持了几天。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