C#字符串编组和LocalAlloc
我需要在C#中使用来自非托管DLL的COM回调。 非托管DLL期望被调用者使用C#字符串编组和LocalAlloc,c#,c++,com,callback,marshalling,C#,C++,Com,Callback,Marshalling,我需要在C#中使用来自非托管DLL的COM回调。 非托管DLL期望被调用者使用LocalAlloc(调用者将LocalFree)分配内存,用WSTR填充它,并分别将value和chars设置为WSTR指针和字符串长度 我正在尝试将代码段转换为C#: 等效的C代码是什么 编辑:COM接口: [id(2)]HRESULT GetString([in]LPCSTR字段,[out]LPWSTR*value,[out]int*chars)最简单的方法是导入函数,使用将字符串转换为字节,并将它们复制到分配的
LocalAlloc
(调用者将LocalFree
)分配内存,用WSTR
填充它,并分别将value
和chars
设置为WSTR指针和字符串长度
我正在尝试将代码段转换为C#:
等效的C代码是什么
编辑:COM接口:
[id(2)]HRESULT GetString([in]LPCSTR字段,[out]LPWSTR*value,[out]int*chars)代码>最简单的方法是导入函数,使用将字符串转换为字节,并将它们复制到分配的内存中。这看起来不像COM代码。最重要的细节是接口声明,请务必向我们展示,因为它可能需要修改。字符串hackery在Marshal.StringToHGlobalUni()中非常简单。@HansPassant谢谢Marshal.StringToHGlobalUni()
正是我要找的。@HansPassant我以为HGLOBAL和HLOCAL不兼容?GlobalAlloc
文档明确指出“使用LocalFree释放分配给GlobalAlloc的内存是不安全的。”尽管名称不同,Marshal类实际上在幕后使用LocalAlloc/free。奇怪的是,Marshal.StringToHGlobalUni
使用LocalAlloc,而不是GlobalAllocFreeHGLobal
,因此封送。StringToHGlobalUni
必须使用LocalAlloc
,或通过LocalFree
与释放兼容的内容,这在这里很重要。这可能更有效、更简单。至少有关于FreeHGlobal
docs的评论。
STDMETHODIMP CMyImpl::GetString(LPCSTR field, LPWSTR* value, int* chars) {
CStringW ret;
if (!strcmp(field, "matrix")) {
ret = L"None";
if (...)
ret.Append(L"001");
else if (...)
ret.Append(L"002");
else
ret.Append(L"003");
}
if (!ret.IsEmpty()) {
int len = ret.GetLength();
size_t sz = (len + 1) * sizeof(WCHAR);
LPWSTR buf = (LPWSTR)LocalAlloc(LPTR, sz);
if (!buf) {
return E_OUTOFMEMORY;
}
wcscpy_s(buf, len + 1, ret);
*chars = len;
*value = buf;
return S_OK;
}
return E_INVALIDARG;
}