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

时间:2013-12-04 21:15:59

标签: c# c++ com native managed

请原谅我,如果之前已经回答过,但我找不到适用于我的解决方案。我已经看到了许多将C#中的字符串传递给C ++的答案,但反过来却没有那么多。 问题是我有一个c ++应用程序,需要加载一个C#dll并传递一个字符串。

在我通过com公开的事情的C#方面。

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类型lib viewer中看到的

[
  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()

当CTR dll接收到BSTR时,BSTR始终为空。除此之外我没有错误,当函数返回并且HRESULT是S_OK时,ret值会改变 我已经尝试通过值传递BSTR也达到同样的效果。

思想?

1 个答案:

答案 0 :(得分:0)

您声明的BSTR没有长度前缀

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

尝试声明如此

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

来自here如果将简单的Unicode字符串作为参数传递给期望BSTR的COM函数,则COM函数将失败。

另外考虑使用CComBSTR或_bstr_t来管理内存(分配和释放OLE堆),以防万一。