【问题标题】:Problems passing a BSTR from native c++ to managed c# dll将 BSTR 从本机 c++ 传递到托管 c# dll 的问题
【发布时间】:2013-12-04 21:15:58
【问题描述】:

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

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

;

发生的情况是 BSTR 在被 C# dll 接收时始终为空。除此之外,我没有收到任何错误,当函数返回并且 HRESULT 为 S_OK 时,ret 值发生了变化。
我尝试过按值传递 BSTR 也达到同样的效果。

想法?

【问题讨论】:

  • 在 public int GetDriverInfo(ref string drivername) 中删除 ref 时运气好吗?
  • 不,我最初的尝试是 GetDriverInfo(string name);它具有将 GetDriverInfo 显示为 GetDriverInfo([in] BSTR) 的 oletype 查看器,但这也会导致空字符串(不是 NULL 只是空的 "" )

标签: c# c++ com native managed


【解决方案1】:

您的 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 堆)。

【讨论】:

  • 完美!这样就解决了问题!! (仍然通过 ref 但我想我可以更改 C# 来删除它)
  • 有趣的是(删除参考后)您可以使用 CComBSTR s(L"c:\\xmltestdir\\cdromarm.sys");并从构造函数初始化中正确分配了 BSTR 而 BSTR s(L"c:\\xmltestdir\\cdromarm.sys");失败。再次感谢!'
  • @Himilou, BSTR s(L"c:....."); 失败,因为 BSTR 不是辅助类;它是simply a typedef for "wchar_t*"。编译器无法区分 BSTR 和纯 Unicode 字符串指针之间的区别,因为 - 就编译器而言 - 它们是完全相同的东西。另一方面,CComBSTR 辅助类知道区别并在其构造函数中调用正确的 API。
猜你喜欢
  • 1970-01-01
  • 2010-12-18
  • 2011-09-02
  • 2011-08-29
  • 2017-02-09
  • 1970-01-01
  • 1970-01-01
  • 2017-10-07
  • 1970-01-01
相关资源
最近更新 更多