我正在尝试在C#代码中使用C编写的DLL(来自Point Grey Research Inc的FlyCapture API),但我总是遇到运行时错误。这里我有两个使用DLL的代码示例:一个是用C ++编写的,另一个是我尝试使用不安全的上下文在C#中做同样的事情。
C ++代码:
void Callback(void* Param, int Message, unsigned long lParam)
{
cout << Message << "\t" << lParam << endl;
}
int main(int argc, char *argv[])
{
void *context;
FlyCaptureCallback *callback = Callback;
flycaptureCreateContext(&context);
flycaptureModifyCallback(context, callback, NULL, true);
_sleep(5000);
flycaptureModifyCallback(context, callback, NULL, false);
flycaptureDestroyContext(context);
return 0;
}
C#代码:
[DllImport("pgrflycapture.dll")]
static extern int flycaptureCreateContext(void** pContext);
[DllImport("pgrflycapture.dll")]
static extern int flycaptureDestroyContext(void* context);
[DllImport("pgrflycapture.dll")]
static extern int flycaptureModifyCallback(void* context, IntPtr pfnCallback, void* pParam, bool bAdd);
delegate void FlyCaptureCallback(void* Param, int Message, uint lParam);
static void Callback(void* Param, int Message, uint lParam)
{
Console.WriteLine(Message.ToString() + "\t" + lParam.ToString());
}
static void Main(string[] args)
{
void *context;
IntPtr callback = Marshal.GetFunctionPointerForDelegate((FlyCaptureCallback) Callback);
flycaptureCreateContext(&context);
flycaptureModifyCallback(context, callback, null, true);
Thread.Sleep(5000);
flycaptureModifyCallback(context, callback, null, false);
flycaptureDestroyContext(context);
}
此程序的目的是注册回调函数,以便在相机总线中发生事件时,调用此函数。程序然后等待5秒钟并从寄存器中删除回调。 C ++应用程序工作正常,如果我在这5秒内从计算机中删除相机,控制台中会出现一条消息。另一方面,C#应用程序仅在没有事件发生时才能正常工作,因此不会调用回调函数。如果我尝试从计算机中删除相机,则会成功调用回调函数并在屏幕上显示正确的数字,但Windows会在函数flycaptureDestroyContext期间显示一条消息“vshost32-clr2.exe已停止工作”。
有什么想法吗?谢谢!
答案 0 :(得分:1)
我知道了!问题是API的函数(flycaptureCreateContext,flycaptureModifyCallback和flycaptureDestroyContext)在C头中声明为__cdecl,但我没有在DllImport语句中考虑它。遵循更正的C#代码:
[DllImport("pgrflycapture.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int flycaptureCreateContext(void** pContext);
[DllImport("pgrflycapture.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int flycaptureDestroyContext(void* context);
[DllImport("pgrflycapture.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int flycaptureModifyCallback(void* context, FlyCaptureCallback pfnCallback, void* pParam, bool bAdd);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate void FlyCaptureCallback(void* Param, int Message, uint lParam);
static void Callback(void* Param, int Message, uint lParam)
{
Console.WriteLine(Message.ToString() + "\t" + lParam.ToString());
}
static void Main(string[] args)
{
void *context;
FlyCaptureCallback callback = (FlyCaptureCallback) Callback;
flycaptureCreateContext(&context);
flycaptureModifyCallback(context, callback, null, true);
Thread.Sleep(5000);
flycaptureModifyCallback(context, callback, null, false);
flycaptureDestroyContext(context);
}
感谢lnmx和Jim Mischel的宝贵帮助!