调用回调函数时出现C#异常

时间:2010-02-17 15:53:07

标签: c# exception callback

我已经让它从C代码调用非托管函数。 pCallback是一个函数指针,因此在托管端是委托。

[DllImport("MyDLL.dll")]

public static extern Result SetCallback(
            IntPtr handle,
            Delegate pCallback,
            CallbackType Type);

现在我正在设置

private delegate void pfnCallback(uint PromptID, ttsEventType evt, IntPtr lData);
private pfnCallback cb = new pfnCallback(cback);

public Form1()
{

    (...)
    Wrapper.SetCallback(handle, cb, IntPtr.Zero, CallBackType.DEFAULT);
    (...)
    public static void cback(uint PromptID, ttsEventType evt, IntPtr lData)
    { }
    }

调试时,我看到它运行一次cback函数,然后我得到一个没有数据的异常,只是说“WindowsApp2.vshost.exe [4372]中发生了未处理的win32异常。我不明白是什么错了。任何人都可以帮助我吗?

4 个答案:

答案 0 :(得分:2)

尝试调用Marshal.GetLastWin32Error()来获取Win32错误代码。

然后将错误代码与此列表进行比较:http://msdn.microsoft.com/en-us/library/ms681381(VS.85).aspx

它仍然不是一个好的异常对象的信息,但它可能指向正确的方向。

答案 1 :(得分:2)

这里没有太多细节,但我的猜测是这可能是一个召集会议问题。我总是尝试在使用DllImport时显式设置调用约定;

[DllImport("msvcrt.dll", CharSet=CharSet.Unicode, CallingConvention=CallingConvention.Cdecl)]
public static extern int printf(String format, int i, double d); 

调用约定可以影响参数在调用堆栈上的放置方式以及之后如何清理它们。

请参阅here

您必须从非托管库提供的标头或文档中找到正确的约定。

答案 2 :(得分:1)

您必须确保垃圾收集器不收集您对回调的引用。只要回调预期被调用,对回调的引用必须在托管内存中保持活动状态。

解决此问题的一种方法是在中间创建一个托管C ++层

答案 3 :(得分:1)

尝试使用

[UnmanagedFunctionPointer(CallingConvention.xxx, CharSet = CharSet.xxx)]
public delegate ...