Ich habe ein C-Callback wie folgt definiert:Problem mit der C-Callback-Funktion in C# - Wie übergibt man einen Wert an einen Zeiger?
Int16 (CALLBACK *ProcessMessage)(Uint16 ServerId,
const char PTR *RequestMsg, Uint32 RequestSize,
char PTR **ResponseMsg, Uint32 PTR *ResponseSize,
Int16 PTR *AppErrCode);
Ein exemple diesen Rückruf in C verwenden:
Int16 CALLBACK ProcessMessage(Uint16 ServerId, const char PTR *RequestMsg, Uint32 RequestSize, char PTR **ResponseMsg, Uint32 PTR *ResponseSize, Int16 PTR *AppErrCode) { printf("ProcessMessage() -> ServerId=%u\n", ServerId); //**** SET THE VALUE FOR RESPONSEMSG (POINTER), THAT'S WHAT I NEED TO DO IN C# **** sprintf(resp,"(%05lu) REPLY TEST", ServerId); *ResponseMsg = resp; printf("ProcessMessage() -> atribuido %p(p) a *ResponseMsg\n", *ResponseMsg); *ResponseSize = strlen(*ResponseMsg); *AppErrCode = -1; return SS_OK; }
Dann habe ich diesen Rückruf in C# implementiert:
[DllImport("Custom.dll", SetLastError = true)]
static extern Int16 SS_Initialize(
UInt16[] ServerIds,
UInt16 ServerQty,
[MarshalAs(UnmanagedType.LPStr)] string Binding,
[MarshalAs(UnmanagedType.LPStr)] string LogPath,
UInt16 LogDays,
Int16 LogLevel,
UInt16 MaxThreads,
UInt16 MaxConThread,
ProcessMessageCallback callback);
Rückruf-Definition:
public delegate Int16 ProcessMessageCallback(
UInt16 ServerId,
[MarshalAs(UnmanagedType.LPStr)] string RequestMsg,
UInt32 RequestSize,
[MarshalAs(UnmanagedType.LPStr)] ref string ResponseMsg,
ref UInt32 ResponseSize,
ref Int16 AppErrCode);
Methode, die die Callback-Sets:
public void Call_SS_Initialize(
UInt16[] serverIds,
string binding,
string logPath,
UInt16 logDays,
Int16 logLevel,
UInt16 maxThreads,
UInt16 maxConThread
)
{
Int16 ret;
try
{
pmc = new ProcessMessageCallback(ProcessMessage);
ret = SS_Initialize(
serverIds,
Convert.ToUInt16(serverIds.ToList().Count),
binding,
logPath,
logDays,
logLevel,
maxThreads,
maxConThread,
pmc);
}
}
Und schließlich die Callback-Methode, wo das Problem liegt: So
public Int16 ProcessMessage(
UInt16 ServerId,
string RequestMsg,
UInt32 RequestSize,
ref string ResponseMsg,
ref UInt32 ResponseSize,
ref Int16 AppErrCode)
{
//Implement return to ResponseMsg POINTER
}
Das Problem ist, ResponseMsg ist eigentlich ein POINTER in C. in der C# -Methode ProcesMessage, muss ich auf ResponseMsg einen Speicherplatz im Speicher (Zeiger) festlegen, woher die DLL die Zeichenfolge erhalten wird.
Ich kann ResponseMsg = "REPLY" nicht einfach festlegen, weil wenn die Methode beendet wird, der Speicher, in dem die Zeichenfolge bereits zerstört wurde.
Wie kann ich das tun ?? Bitte jede Beratung ist willkommen !!
Danke!
Das sieht auf den ersten Blick für mich OK. Wenn Sie ResponseMsg in Ihrem C# -Handler festlegen, was erhalten Sie dann wieder am C-Ende? Ein Debugfehler? Müll? Nichts? –
Ich glaube, dass 'ref' dort eine doppelte Indirektion gibt - d. H. Er gibt kein' char * 'dort, sondern' char ** '. –
Ah, tut mir leid, verpasste die Tatsache, dass es in der Tat ist, was erforderlich ist! –