将BSTR字符串作为托管和非托管代码之间的边界传递(COM互操作)

时间:2019-01-09 10:13:18

标签: c# c++ com bstr managed-code

在进行com interop时,我遵循了link上的教程。代码运行良好,因为我根据自己的要求进行了一些修改,但是问题是在处理字符串时出现的。我正在使用BSTR字符串这里作为周长。 这是我从c ++调用的c#中的函数

  public  string ShowDialog([MarshalAs(UnmanagedType.BStr)] string stringToPrint)
    {
      //  Console.WriteLine(" Enter TOTP input:");
       // stringToPrint = Console.ReadLine();

        if (stringToPrint == "111111")
        {

            MessageBox.Show("true");



        }
        else
        {
            MessageBox.Show("false");

        }

        return stringToPrint;
    }

这是我的代码的C ++主要功能部分,

CoInitialize(NULL);

MyInterop::IMyDotNetInterfacePtr pDotNetCOMPtr;

HRESULT hRes = pDotNetCOMPtr.CreateInstance(MyInterop::CLSID_MyDotNetClass);
if (hRes == S_OK)
{

    BSTR lResult ;

    cout << "enter TOTP input" << endl;

    _bstr_t bstrStatus = SysAllocString(L"111111");

    pDotNetCOMPtr->ShowDialog(bstrStatus,&lResult);

    SysFreeString(bstrStatus);


}

CoUninitialize();

system("pause");

这是输出 enter image description here

我面临的问题如下:

  • 虽然我在c#中使用返回函数,但是从C ++代码传递后,BSTR字符串未在控制台上返回。
  • 是否有可能像我在使用 SysAllocString(“”)一样在控制台上动态插入输入,从而使其难以编码。

1 个答案:

答案 0 :(得分:0)

使用Visual Studio和#import指令时,生成的代码使用_bstr_t,它是BSTR(原始Windows类型)上的智能包装类。

因此,您不必使用SysAllocString或SysFreeString,您可以非常自然地使用_bstr_t。例如,在您的情况下,如果您的C#方法签名如下:

public string ShowDialog(string stringToPrint) // you don't need the MarshalAs here, the TLB will build it as a BSTR

然后您可以使用如下的C ++代码:

... other imports or includes
// import mscorlib so we have a full generated cool code (I recommend not to use raw_interfaces_only)
// we rename 'or' to something that doesn't pose problems. Your mileage can vary depending on your building context...
#import "C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.tlb" rename("or","whatever")
#import "C:\myPath\MyClassLibrary1.tlb" // adapt to your path

int main()
{
  CoInitialize(NULL);
  {
    MyClassLibrary1::_Class1Ptr ptr;
    HRESULT hr = ptr.CreateInstance(__uuidof(MyClassLibrary1::Class1)); // should return S_OK/0

    _bstr_t input = L"111111";
    _bstr_t res = ptr->ShowDialog(input); // assign the return string
    wprintf(L"res:%s\n", res.GetBSTR()); // output (unicode) result to console
  }
  CoUninitialize();
}

您也可以直接这样写:

_bstr_t res = ptr->ShowDialog(L"111111");

//或此(具有自动从ANSI到Unicode的转换)

_bstr_t res = ptr->ShowDialog("111111");

所有_bstr_t都会自动分配和释放。