如果這個函數分配內存,並讓負責釋放它的調用者,恐怕你得手動管理:將該參數聲明爲ref IntPtr
,並使用Marshal
類的方法獲取帶有指向數據副本的字符串。
然後調用相應的函數釋放內存(正如Dirk所說的,我們不能在沒有關於函數的更多信息的情況下多說這些)。
如果真的必須在調用之前進行分配,它應該是這樣看:
[DllImport("yourfile.dll", CharSet = CharSet.Ansi)]
public static extern sbyte service_GetParameter (String parameter, Int32 length, ref IntPtr val);
public static string ServiceGetParameter(string parameter, int maxLength)
{
string ret = null;
IntPtr buf = Marshal.AllocCoTaskMem(maxLength+1);
try
{
Marshal.WriteByte(buf, maxLength, 0); //Ensure there will be a null byte after call
IntPtr buf2 = buf;
service_GetParameter(parameter, maxLength, ref buf2);
System.Diagnostics.Debug.Assert(buf == buf2, "The C++ function modified the pointer, it wasn't supposed to do that!");
ret = Marshal.PtrToStringAnsi(buf);
}
finally { Marshal.FreeCoTaskMem(buf); }
return ret;
}
僅供參考,我認爲你的C++是有點狡猾。什麼'service_GetParameter'正在做的是通過'* value'返回一個指向字符的指針。所以你的'delete [] val'會刪除返回的指針,而不是你分配的原始內存。如果沒有'new'和'delete',只寫'char * val = 0',你會更好。 – TooTone
我不認爲有一個有效的答案,不知道更多關於'service_GetParameter'函數。它分配內存嗎?或者它可能會返回一個指向某個內部字符串的指針?如果調用者必須分配內存,爲什麼使用'char **'? – Dirk
service_GetParameter不分配內存。調用者必須分配內存,調用service_GetParameter並釋放內存(在C++中使用delete [])。 – LukeT