Penso di aver praticamente capito come scrivere i delegati C# per i callback, ma questo mi confonde. Il C++ definizione è la seguente:C# delegate per callback C++
typedef int (__stdcall* Callback)(
long lCode,
long lParamSize,
void* pParam
);
e il mio C# approccio sarebbe:
unsafe delegate int CallbackDelegate (int lCode, int lParamSize, IntPtr pParam);
Anche se questo sembra essere corretto, perché ricevo un errore di PInvokeStackInbalance, il che significa che la mia definizione del delegato è sbagliato.
Il resto dei parametri della funzione sono stringhe o int, il che significa che non possono causare l'errore, e se ho appena passato un IntPtr.Zero invece del delegato (il che significherebbe che sto puntando a un non- funzione di callback esistente) Ricevo un errore di AccessViolation, che ha anche un senso.
Cosa sto sbagliando?
EDIT: la funzione
La piena C++ è:
int
__stdcall
_Initialize (
const char* FileName,
Callback cbFunction,
int Code,
const char* Name,
unsigned int Option,
unsigned int Option2
);
mio C# versioni:
[DllImport("MyDll.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int _Initialize (string FileName, CallbackDelegate cbFunction, int Code, string Name, uint Options, uint Options2);
La funzione è (per la prova) appena chiamato all'interno della routine principale un'applicazione console:
static void Main(string[] args)
{
CallbackDelegate del = new CallbackDelegate(onCallback);
Console.Write(_Initialize("SomeFile.dat", del, 1000, "", 0, 4));
Console.Read();
}
dove onCallback
è questo:
static int onCallback(int lCode, int lParamSize, IntPtr pParam)
{
return 0;
}
ottengo l'errore PInvokeStackInbalance
nella riga in cui chiamo _Initialize
, se mi passa un IntPtr.Zero
invece del delegato, e cambiare la definizione della funzione di IntPtr
anziché CallbackDelegate
poi Ottengo un AccessViolationException
.
'Il resto dei parametri della funzione sono stringhe o intarsi'. Non nascondere le informazioni. –
Hai provato a non usare insicuro? i.e: delegate int CallbackDelegate (int lCode, int lParamSize, IntPtr pParam); – DougEC
@HansPassant Non sto cercando di nascondere le informazioni, stavo cercando di lasciare le cose che considero non rilevanti. Modificherò la domanda e aggiungerò le informazioni. – Valandur