C++COM中C#的字符串

本文关键字:字符串 C++COM | 更新日期: 2023-09-27 18:27:45

我有一个C++DLL,一些函数返回以Unicode null结尾的字符串:

void SomeFunc(wchar_t* StrBuf)

调用方必须分配StrBuf-字符串最多可以是256个字符。这个DLL还公开了一个COM对象,以便通过COM从C#使用这个DLL。IDL:中的定义

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

目前,C#代码如下所示:

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

有没有一种方法可以定义这样一个COM函数,以便从C#更容易地使用它?现在它看起来很难看,调用函数需要三行,如果函数有两个字符串参数,则需要五行。

C++COM中C#的字符串

如果将其作为COM对象公开,只需使用visualstudio添加对对象的引用即可。它将自动为您生成一个程序集(我相信他们称之为COM可调用包装器)。

这将向.NET公开COM对象方法,并且除非您开始尝试传递一些自定义结构,否则可以正常工作。

以下是一些资源:

COM可调用包装

COM互操作第1部分:C#客户端教程

如果客户端中字符串的内存分配并填充到COM服务器,则必须使用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);

然后StringBuilder将为空或填充字符。

已解决。在C++中,我在COM包装器中使用以下代码:

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

在C#中,它现在可以很容易地调用:

string val;
MyComObj.SomeFunc(out val);