将 wchar_t** 从 C++ 编组到 C# 作为输出参数?
Marshal wchar_t** from C++ to C# as an out parameter?
我在 C 的 dll 中有这个函数,我无法更改它:
extern "C" SIBIO_MULTILANGUAGE_API_C DWORD getLabel(const char* const i_formName,
const char* const i_fieldName,
wchar_t** i_output);
我知道这个内部调用使用函数 CoTaskMemAlloc
.
为 wchar_t*
分配内存
在 C# 中,我以这种方式包装了这个函数:
[DllImport("sibio_multilanguage_c.dll", EntryPoint = "getLabel", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt32 _getLabel([In] string i_formName, [In] string i_fieldName,
[MarshalAs(UnmanagedType.LPWStr)] out string i_output);
static public string getLabel(string i_formName, string i_fieldName)
{
string str = null;
UInt32 err = _getLabel(i_formName, i_fieldName, out str);
if (0 != err)
{
throw new System.IO.FileNotFoundException();
}
return str;
}
我能够正确读取 wchar_t*
的内容,但是以这种方式读取我没有释放 C 函数中分配的内存。
我怎样才能阅读 wchar_t*
并且能够释放它?非常感谢任何帮助!
感谢@Dai 和@IanAbbot 的评论,我想出了一个完美的解决方案:
[DllImport("sibio_multilanguage_c.dll", EntryPoint = "getLabel", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt32 _getLabel([In] string i_formName, [In] string i_fieldName,
out IntPtr i_output);
static public string getLabel(string i_formName, string i_fieldName)
{
IntPtr i_result;
string str = null;
UInt32 err = _getLabel(i_formName, i_fieldName, out i_result);
if (0 != err)
{
throw new System.IO.FileNotFoundException();
}
str = Marshal.PtrToStringAuto(i_result);
Marshal.FreeCoTaskMem(i_result);
return str;
}
我在 C 的 dll 中有这个函数,我无法更改它:
extern "C" SIBIO_MULTILANGUAGE_API_C DWORD getLabel(const char* const i_formName,
const char* const i_fieldName,
wchar_t** i_output);
我知道这个内部调用使用函数 CoTaskMemAlloc
.
wchar_t*
分配内存
在 C# 中,我以这种方式包装了这个函数:
[DllImport("sibio_multilanguage_c.dll", EntryPoint = "getLabel", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt32 _getLabel([In] string i_formName, [In] string i_fieldName,
[MarshalAs(UnmanagedType.LPWStr)] out string i_output);
static public string getLabel(string i_formName, string i_fieldName)
{
string str = null;
UInt32 err = _getLabel(i_formName, i_fieldName, out str);
if (0 != err)
{
throw new System.IO.FileNotFoundException();
}
return str;
}
我能够正确读取 wchar_t*
的内容,但是以这种方式读取我没有释放 C 函数中分配的内存。
我怎样才能阅读 wchar_t*
并且能够释放它?非常感谢任何帮助!
感谢@Dai 和@IanAbbot 的评论,我想出了一个完美的解决方案:
[DllImport("sibio_multilanguage_c.dll", EntryPoint = "getLabel", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt32 _getLabel([In] string i_formName, [In] string i_fieldName,
out IntPtr i_output);
static public string getLabel(string i_formName, string i_fieldName)
{
IntPtr i_result;
string str = null;
UInt32 err = _getLabel(i_formName, i_fieldName, out i_result);
if (0 != err)
{
throw new System.IO.FileNotFoundException();
}
str = Marshal.PtrToStringAuto(i_result);
Marshal.FreeCoTaskMem(i_result);
return str;
}