【问题标题】:C# exception when calling callback function调用回调函数时的C#异常
【发布时间】:2010-02-17 15:53:06
【问题描述】:

我这样做是为了从 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中发生未处理的win32异常[4372]。我不明白是什么错了。谁能帮帮我?

【问题讨论】:

    标签: c# exception callback


    【解决方案1】:

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

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

    它仍然没有一个好的异常对象那么多的信息,但它可能会为您指明正确的方向。

    【讨论】:

      【解决方案2】:

      这里没有太多细节,但我猜这可能是调用约定问题。使用 DllImport 时,我总是尝试显式设置调用约定;

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

      调用约定会影响参数在调用堆栈中的放置方式以及之后的清理方式。

      here

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

      【讨论】:

        【解决方案3】:

        尝试使用

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

        【讨论】:

          【解决方案4】:

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

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

          【讨论】:

            猜你喜欢
            • 2017-11-27
            • 2014-07-10
            • 1970-01-01
            • 1970-01-01
            • 2013-11-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-06-25
            相关资源
            最近更新 更多