Myślę, że zasadniczo zrozumiałem, jak pisać C# delegatów dla wywołań zwrotnych, ale ten jest mylący. C++ definicja jest następująca:Delegat C# do wywołania C++
typedef int (__stdcall* Callback)(
long lCode,
long lParamSize,
void* pParam
);
i moja C# podejście byłoby:
unsafe delegate int CallbackDelegate (int lCode, int lParamSize, IntPtr pParam);
Mimo to wydaje się być nieprawidłowy, ponieważ pojawia się błąd PInvokeStackInbalance, co oznacza moją definicję delegata jest źle.
Pozostałe parametry funkcji są ciągami lub intami, co oznacza, że nie mogą powodować błędu, a jeśli po prostu przekazuję IntPtr.Zero zamiast delegata (co oznaczałoby, że wskazuję na istniejąca funkcja oddzwaniania) Otrzymuję błąd AccessViolation, który ma również sens.
Co robię źle?
EDIT: funkcja
Pełne C++ to:
int
__stdcall
_Initialize (
const char* FileName,
Callback cbFunction,
int Code,
const char* Name,
unsigned int Option,
unsigned int Option2
);
Moje C# wersja jest:
[DllImport("MyDll.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int _Initialize (string FileName, CallbackDelegate cbFunction, int Code, string Name, uint Options, uint Options2);
Funkcję (do testowania) nazywany po prostu wewnątrz głównego rutyny aplikacja konsolowa:
static void Main(string[] args)
{
CallbackDelegate del = new CallbackDelegate(onCallback);
Console.Write(_Initialize("SomeFile.dat", del, 1000, "", 0, 4));
Console.Read();
}
gdzie onCallback
to:
static int onCallback(int lCode, int lParamSize, IntPtr pParam)
{
return 0;
}
pojawia się błąd PInvokeStackInbalance
na linii, gdzie ja nazywam _Initialize
, jeśli mijam IntPtr.Zero
zamiast delegata i zmienić definicję funkcji do IntPtr
zamiast CallbackDelegate
następnie Otrzymuję AccessViolationException
.
'Reszta parametrów funkcji są stringi lub ints'. Nie ukrywaj informacji. –
Czy próbowałeś nie używać niebezpieczeństwa? tj .: delegować int CallbackDelegate (int lCode, int lParamSize, IntPtr pParam); – DougEC
@HansPassant Nie próbuję ukrywać informacji, próbowałem zostawić rzeczy, które uważałem za nieistotne. Będę edytować pytanie i dodać informacje. – Valandur