У меня есть обратный вызов C, определенный следующим образом:
Int16 (CALLBACK *ProcessMessage)(Uint16 ServerId,
const char PTR *RequestMsg, Uint32 RequestSize,
char PTR **ResponseMsg, Uint32 PTR *ResponseSize,
Int16 PTR *AppErrCode);
Пример использования этого обратного вызова в C:
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;
}
Тогда я реализовал этот обратный вызов в C #:
[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);
Определение обратного вызова:
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);
Метод, который устанавливает обратный вызов:
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);
}
}
И, наконец, метод обратного вызова, где ПРОБЛЕМА ЕСТЬ:
public Int16 ProcessMessage(
UInt16 ServerId,
string RequestMsg,
UInt32 RequestSize,
ref string ResponseMsg,
ref UInt32 ResponseSize,
ref Int16 AppErrCode)
{
//Implement return to ResponseMsg POINTER
}
Проблема в том, что ResponseMsg на самом деле является POINTER в C. Поэтому в методе C # ProcesMessage я должен установить для ResponseMsg пробел в память (указатель), откуда DLL будет получать строку.
Я не могу просто установить ResponseMsg = "REPLY", потому что, когда метод заканчивает память, где строка уже уничтожена.
Как я могу это сделать ?? Пожалуйста, любые советы приветствуются !!
Спасибо!