将BSTR从本机c++传递到托管c#dll时出现问题

Problems passing a BSTR from native c++ to managed c# dll

本文关键字:c#dll 问题 BSTR 本机 c++      更新时间:2023-10-16

如果以前有人回答过这个问题,请原谅,但我还没有找到适合我的解决方案。我看到过很多将字符串从C#传递到C++的答案,但没有那么多相反的答案。问题是我有一个c++应用程序,它需要加载一个c#dll并向它传递一个字符串。

在C#方面,我已经通过com.公开了这一点

namespace DriverCollect
{
    public interface IDriverInfo
    {
        int GetDriverInfo(ref string name);
    };

    public class DriverInterface:IDriverInfo
    {
        public int GetDriverInfo(ref string drivername)
        {
            DriverInfo myInfo = new DriverInfo(@"c:logfile.txt") ;
            myInfo.Collect(drivername);
            return 0;
        }
    }
}

我用regasm注册了tbl文件,这就是我在OLE类型库查看器中看到的

[
  odl,
  uuid(F3005FE7-DBA1-3FB6-807E-E66626EC875B),
  version(1.0),
  dual,
  oleautomation,
  custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "DriverCollect.IDriverInfo")
]
interface IDriverInfo : IDispatch {
    [id(0x60020000)]
    HRESULT GetDriverInfo(
                    [in, out] BSTR* name, 
                    [out, retval] long* pRetVal);
};

在C++方面,这是我的测试用例。

HRESULT hr = CoInitialize(NULL);
IDriverInfoPtr pDriverInfo(__uuidof(DriverInterface));
if(pDriverInfo)
   m_pDriverInfo = pDriverInfo;
BSTR s(L"c:\xmltestdir\cdromarm.sys");
long ret = 1;
hr = m_pDriverInfo->GetDriverInfo(&s,&ret);
CoUninitialize()

发生的情况是,当C#dll接收到BSTR时,它总是空的。除此之外,我没有得到任何错误,当函数返回并且HRESULT为S_OK时,ret值会发生更改
我尝试过通过值传递BSTR,也达到了同样的效果。

想法?

您的BSTR在声明为时没有长度前缀

BSTR s(L"c:\xmltestdir\cdromarm.sys");

尝试将其声明为

BSTR s = SysAllocString(L"c:\xmltestdir\cdromarm.sys");

从这里开始,如果将一个简单的Unicode字符串作为参数传递给需要BSTR的COM函数,则COM函数将失败

此外,还可以考虑使用CComBSTR或_bstr_t,以便在出现异常时为您管理内存(从OLE堆中分配和释放)。