String for C# from C++ COM

2019-07-05 02:45发布

问题:

I have a C++ DLL and some functions return Unicode null-terminated strings:

void SomeFunc(wchar_t* StrBuf)

The caller must allocate StrBuf - string can be up to 256 characters. This DLL also exposes a COM object to use this DLL from C# via COM. Definition in IDL:

[id(1), helpstring("bla")]
HRESULT SomeFunc([in,out] BSTR* TextStr, [out,retval] LONG* RetValue);

Currently the C# code looks like this:

string val = new string('\0', 256); // Allocate memory
MyComObj.SomeFunc(ref val); // Get string
val = val.Substring(0, val.IndexOf('\0')); // Convert from null-terminated string

Is there a way to define such a COM function so it can be used from C# easier? Right now it looks ugly and takes three lines to call the function or five lines if a function has two string parameters.

回答1:

If you have this exposed as a COM object, just use visual studio to add a reference to your object. It will automatically generate an assembly for you (I believe they call this a COM callable wrapper).

This will expose your COM objects methods to .NET and works unless you start trying to pass across some custom structures.

Here are some resources for you:

COM Callable Wrapper

COM Interop Part 1: C# Client Tutorial



回答2:

If the memory for the string in the client allocates and fills it to the COM server, you must use a StringBuilder:

// IDL code
HRESULT GetStr(/*[out]*/ LPSTR pStr);

// Interop
void GetStr(/*[out]*/ [MarshalAs(UnmanagedType.LPStr)] StringBuilder pStr);

// C# code
var str = new StringBuilder(256);
MyComObj.GetStr(a);

Then the StringBuilder will be empty or filled with characters.



回答3:

Solved. In C++ I use this code in the COM wrapper:

STDMETHODIMP MyClassClass::SomeFunc(BSTR* OptionValue, LONG* RetValue)
{
    *RetValue = 0;
    UNICODECHAR txt[MAXSTATSTRLEN];

    //... Copy text to txt variable
    *OptionValue = W2BSTR(txt);
    return S_OK;
}

IDL:

[id(1), helpstring("")] HRESULT SomeFunc([out] BSTR* OptionValue, [out,retval] LONG* RetValue);

In C# it can now be called easily:

string val;
MyComObj.SomeFunc(out val);


标签: c# c++ string com