【发布时间】:2009-08-06 20:04:27
【问题描述】:
我有一个 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); //**** 设置 RESPONSEMSG 的值(指针),这就是我需要在 C# 中做的事情 **** sprintf(resp,"(%05lu) 回复测试", ServerId); *ResponseMsg = resp; printf("ProcessMessage() -> atribuido %p(p) a *ResponseMsg\n", *ResponseMsg); *ResponseSize = strlen(*ResponseMsg); *AppErrCode = -1; 返回 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。所以在C#方法ProcesMessage中,我必须设置为ResponseMsg DLL 将从中获取字符串的内存空间(指针)。
我不能简单地设置 ResponseMsg = "REPLY",因为当方法完成时,字符串已经被销毁的内存。
我该怎么做?欢迎任何建议!
谢谢!
【问题讨论】:
-
乍一看,这看起来不错。当您在 C# 处理程序中设置 ResponseMsg 时,您会在 C 端返回什么?调试错误?垃圾?什么都没有?
-
我认为在那里使用
ref会给他双重间接 - 即他实际上并没有在那里传递char*,而是char**。 -
啊,对不起,错过了它确实是需要的事实!
-
Ben,字符串似乎被垃圾处理了,因为 C 程序在 ResponseMsg 变量上一无所获。 Pavel,我对 C 编程几乎一无所知……你能解释得更好吗?
-
仔细看:PTR的定义是什么? ResponseMsg 被定义为
char PTR **.. 那是char ***吗?因为那行不通。 :-)
标签: c# c memory callback pointers