2010-02-17 67 views
3

我使用C代码调用了非托管函数。 pCallback是一个函数指针,所以托管端是一个委托。调用回调函数时出现C#异常

[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功能一次,然后我得到一个异常没有数据,只是说“发生未处理的win32异常WindowsApp2.vshost.exe [4372]我不明白什么是错的。谁能帮我?

回答

1

尝试使用

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

它的工作!非常感谢你! – jose 2010-02-17 16:18:01

1

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

一去解决这个办法是在中间

2

创建一个托管C++层没有很多的细节在这里,但我的猜测是,这可能是一个调用约定的问题。我总是尝试在使用DllImport时明确设置调用约定;

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

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

here

你不得不找到提供非托管库的标题或文档正确的约定。

相关问题