C # C ++ Wywołanie wewnętrzne Interop
Niedawno majstrowałem przy interopie C # z C ++, szczególnie konfigurując funkcję wywołania zwrotnego, która jest wywoływana z biblioteki DLL C ++.
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;
}
}
}
Mam pytanie, że gdy kontrolka programu wchodzi w funkcję TomCallback, oczekiwałem, że następnie trafi w pętlę while (true) w Main. Jednak zamiast tego program kończy działanie. Nie jestem w stanie skupić się na zachowaniu, część mnie wyobraża sobie, że jest tak, jak się spodziewano, ale część mnie oczekiwałaby, że będzie kontynuowana w głównym.
Czego oczekiwałem ...
Wywoływana jest funkcja GetData ()Funkcja GetData wywołuje wywołanie zwrotneFunkcja zwrotna powraca do GetDataGetData wraca do main ()Nie jest to jednak w porządku.
Czy ktoś byłby na tyle uprzejmy, aby wyjaśnić, co się dzieje.
Aby zaoszczędzić miejsce, nie opublikowałem kodu niezarządzanego, ale jeśli jest potrzebny, chętnie go opublikuję
Edytować: Włączyłem niezarządzane debugowanie (całkowicie zapomniałem tego zrobić) i teraz widzę awarię.
Run-Time Check Failure # 0 - Wartość ESP nie została prawidłowo zapisana w wywołaniu funkcji. Zwykle jest to wynikiem wywołania funkcji zadeklarowanej za pomocą jednej konwencji wywołującej ze wskaźnikiem funkcji zadeklarowanym z inną konwencją wywoływania.
Natywny kod, ponieważ jest to miejsce awarii
#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);
}