使用C#中的委托作为C DllImported函数的回调

时间:2011-08-02 09:01:21

标签: c# c delegates callback dllimport

我正在尝试调用C DLL的函数。

但是我得到了一个StackOverflowException,所以我觉得函数作为参数有问题。

详细看起来像这样。

C DLL(头文件):

typedef struct
{
  MyType aType;     /* message type */
  int nItems;       /* number of items */
   const MyItems    *lpItem;    /* pointer to array of items */
} MyStruct;

typedef void (__stdcall *MyCbFunc) (HWND, const MyStruct  *);

API(BOOL) RegisterCbFunc (ARGS, MyCbFunc);

在C#中我尝试了这个:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct MyStruct
{
  MyType aType;
  int nItems;
  MyItems[] lpItem;
}

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void CallbackDelegate(MyStruct mStruct);

[DllImport("MY.dll", CallingConvention=CallingConvention.StdCall)]
private static extern int RegisterCbFunc(IntPtr hWnd, Delegate pCB);

public static void MyCbFunc(MyStruct mStruct)
{
  // do something
}

static void Main(string[] args)
{
  CallbackDelegate dCbFunc = new CallbackDelegate(MyCbFunc);
  int returnValue = RegisterCbFunc(IntPtr.Zero, dCbFunc);
  // here, returnValue is 1
}

这会运行一段时间,直到DLL调用回调函数。然后我收到了一个错误:

An unhandled exception of type 'System.StackOverflowException' occurred in Microsoft.VisualStudio.HostingProcess.Utilities.dll

感谢您的帮助。

解答: 我不知道为什么,但有一个答案现在被删除了?!

我尝试恢复它。解决方案是使用引用调用而不是函数参数的值调用。

public delegate void CallbackDelegate(ref MyStruct mStruct);

1 个答案:

答案 0 :(得分:1)

你的C函数期望一个指向MyStruct的指针,但你告诉C#它想要一个指向函数的指针。函数和结构之间的区别是......重要的。也许尝试像

这样的东西
[DllImport("MY.dll", CallingConvention=CallingConvention.StdCall)]
private static extern int RegisterCbFunc(IntPtr hWnd, Delegate pCB);

static void Main(string[] args)
{
MyStruct mStruct;
int returnValue = RegisterCbFunc(IntPtr.Zero, mStruct);
}

如果你的C函数用自己分配的东西填充了MyStruct的lpItem成员,我不知道接下来会发生什么,但至少它不会试图覆盖你的代码。