C#C ++ Interop回调 [英] C# C++ Interop callback
问题描述
我最近一直在修改C#到C ++互操作,特别是设置了从C ++ DLL调用的回调函数。
I have recently been tinkering around with C# to C++ interop, in particularly setting up a callback function which is called from the 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)循环。但是,该程序只是退出。我无法完全理解这种行为,我的一部分认为这是预期的,但我的一部分会预期它会在主要方面继续。
The question I have is that, when the program control comes into the TomCallback function, I was expecting it to then hit the while(true) loop in Main. However instead the program just exits. I can't quite get my head round the behaviour, part of me imagines this is as expected but part of me would have expected it to continue on in main.
我期望...
- 调用GetData()函数
- 调用GetData函数回调
- 回调函数返回到GetData
- GetData返回到main()
- The GetData() function is called
- The GetData function calls the callback
- The callback function returns back to GetData
- GetData returns back to main()
但是这不是很正确。
有人会很友好地解释发生了什么。
Would someone be kind enough to explain what happens.
为了节省空间,我没有发布非托管代码,但是如果需要,我很乐意发布
In order to save space I haven't posted the unmanaged code, however if it is needed i'm happy to post
编辑:
我打开了非托管调试(完全忘了这样做),现在我看到了崩溃。.
I turned on Unmanaged debugging (totally forgot to do this) and now I see the crash..
运行时检查失败#0-在整个函数调用中ESP的值未正确保存。这通常是由于使用一种调用约定声明的函数和使用另一种调用约定声明的函数指针进行调用的结果。
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
本机代码因为这是崩溃的地方
Native code as this is where crash is
#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);
}
推荐答案
您必须转换托管回调通过使用
You must convert your managed callback to the Native Function Pointer (IntPtr in C#) by using the
IntPtr Marshal.GetFunctionPointerForDelegate(Delegate d)
方法。
SetCallback()与System的配合使用。
Your usage of SetCallback() with System.Delegate as an argument is wrong.
使之成为
SetCallback(Marshal.GetFunctionPointerForDelegate(lTD));
并将SetCallback重新声明为
and redeclare SetCallback as
/// StdCall is crucial here
[DllImport("TomDllNative.dll", CallingConvention = CallingConvention.StdCall)]
public static extern void SetCallback(IntPtr aCallback);
这篇关于C#C ++ Interop回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!