在将C编写的DLL调用到C#时,vshost32-clr2.exe出错

时间:2013-08-13 18:43:55

标签: c# delegates dllimport calling-convention

我正在尝试在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已停止工作”。

有什么想法吗?谢谢!

1 个答案:

答案 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的宝贵帮助!