【发布时间】:2012-05-31 20:50:52
【问题描述】:
我最近一直在修补 C# 到 C++ 的互操作,特别是设置一个从 C++ DLL 调用的回调函数。
namespace TomCSharpDLLImport
{
class Program
{
public delegate void TomDelegate(int a, int b);
[DllImport("TomDllNative.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void GetData();
[DllImport("TomDllNative.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void SetCallback(TomDelegate aCallback);
static void Main(string[] args)
{
TomDelegate lTD = new TomDelegate(Program.TomCallback);
SetCallback(lTD); //Sets up the callback
int thread = Thread.CurrentThread.ManagedThreadId;
GetData(); //This calls the callback in unmanaged code
while (true) ;
}
//Callback function which is called from the unmanaged code
public static void TomCallback(int a, int b)
{
Console.WriteLine("A: {0} B: {1}", a, b);
int thread = Thread.CurrentThread.ManagedThreadId;
}
}
}
我的问题是,当程序控制进入 TomCallback 函数时,我希望它会在 Main 中运行 while(true) 循环。然而,程序只是退出。我无法完全理解这种行为,我的一部分人认为这是预期的,但我的一部分人会预计它会继续主要。
我所期待的……
- 调用 GetData() 函数
- GetData 函数调用回调
- 回调函数返回GetData
- GetData 返回到 main()
然而这并不完全正确。
有人能解释一下发生了什么吗?
为了节省空间,我没有发布非托管代码,但是如果需要,我很乐意发布
编辑: 我打开了非托管调试(完全忘了这样做),现在我看到了崩溃..
运行时检查失败 #0 - ESP 的值未在函数调用中正确保存。这通常是用一个调用约定声明的函数和一个用不同调用约定声明的函数指针调用的结果。
本地代码,因为这是崩溃的地方
#include "stdafx.h"
typedef void (*callback_function)(int, int);
extern "C" __declspec(dllexport) void SetCallback(callback_function aCallback);
extern "C" __declspec(dllexport) void GetData();
callback_function gCBF;
__declspec(dllexport) void SetCallback(callback_function aCallback)
{
gCBF = aCallback;
}
__declspec(dllexport) void GetData()
{
gCBF(1, 2);
}
【问题讨论】: