C# string marshalling and LocalAlloc

2019-03-05 17:17发布

问题:

I have a COM callback from an unmanaged DLL that I need to use in C#. The unmanaged DLL expects the callee to allocate memory using LocalAlloc (which the caller will LocalFree), populate it with WSTR and set value and chars to the WSTR pointer and string length respectively.

Code snippet I'm trying to convert to C#:

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; 
}

What would the equivalent C# code be?

EDIT: COM Interface:

[id(2)] HRESULT GetString([in] LPCSTR field, [out] LPWSTR* value, [out] int* chars);

回答1:

Straightforward way would be to import LocalAlloc function, convert the string to bytes using UnicodeEncoding.GetBytes and copy them to allocated memory with Marshall.Copy.