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.
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
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.
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);