私は次のように定義されたCコールバックしました:C#のCコールバック関数の問題点 - ポインタに値を渡す方法?
Int16 (CALLBACK *ProcessMessage)(Uint16 ServerId,
const char PTR *RequestMsg, Uint32 RequestSize,
char PTR **ResponseMsg, Uint32 PTR *ResponseSize,
Int16 PTR *AppErrCode);
Cで、このコールバックを使用してのexemple:
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だから、実際にC.でPOINTERで、ありますProcesMessageでは、DLLが文字列を取得するメモリ(ポインタ)のスペースをResponseMsgに設定する必要があります。
単純にResponseMsg = "REPLY"を設定することはできません。これは、メソッドが終了した時点で、文字列がすでに破棄されていたメモリが終了するためです。
どうすればいいですか?アドバイスをお願いします歓迎!!
ありがとうございます!
これは、一目見ただけで私にはOKに見えます。あなたのC#ハンドラでResponseMsgを設定すると、Cの最後に何が戻ってきますか?デバッグエラー?ごみ?何もない? –
'ref'を使うと二重間接指定ができると思います。実際には' char * 'を渡すのではなく、' char ** 'を渡します。 –
ああ、申し訳ありませんが、本当に必要なものであるという事実を逃しました! –