【问题标题】:Access violation when passing BSTR string to _bstr_t or CComBSTR constructor将 BSTR 字符串传递给 _bstr_t 或 CComBSTR 构造函数时访问冲突
【发布时间】:2013-08-12 21:00:05
【问题描述】:

我有从 COM 服务器传递的 BSTR 字符串。当我将此字符串放入 _bstr_t(或 CComBSTR)构造函数时,就会发生访问冲突。我检查了这个异常,发现只有当 BSTR 为空(或 null)时才会引发这个异常。

我试图将无效的 BSTR 显式放入 _bstr_t 构造函数,这工作正常:

BSTR bstr = NULL;
_bstr_t t(bstr, false); 

cout << t.length() << endl;

但是对于从 COM 服务器传递的 BSTR,这不起作用 - 当字符串为空或 null(或者可能已损坏?)时会发生访问冲突异常

我发现这个解决方法很好用:

if (SysStringLen(bstrFromCOMserver) > 0) {
    _bstr_t t(bstrFromCOMserver, false);    
    cout << t.length() << endl;
}

但我想知道为什么这不能直接与 _bstr_t 或 CComBSTR 包装器一起使用:

_bstr_t t(bstrFromCOMserver, false);
if (t.length() > 0) {...}

更新:

COM服务器如何传递BSTR字符串:

void CALLBACK CProxy_ISTIQuoteEvents::OnSTIQuoteSnap(const structSTIQuoteSnap& structQuoteSnap) const { 
        if (SysStringLen(structQuoteSnap.bstrUpdateTime) > 0) {
            _bstr_t updateTime(structQuoteSnap.bstrUpdateTime, false);
        }
    }
}

【问题讨论】:

  • 你能说明你如何调用 COM 服务器吗?例如:CComBSTR str; server-&gt;GetString(&amp;str);
  • 我添加了代码和平。 BSTR 字符串是结构的字段,通过引用传递给事件处理程序。
  • 对不起,我还是不明白。 OnSTIQuoteSnap 是你的 COM 服务器的方法吗?如果是这样,您实际上如何返回字符串?无论如何,这段代码看起来是错误的。您的 _bstr_t updateTime(structQuoteSnap.bstrUpdateTime, false) 只是一个自动堆栈变量。因为您在其构造函数中指定了false,所以它会接管传递的 BSTR 字符串,并在它超出其 {} 范围后立即释放它。也许这就是问题所在。
  • 如果OnSTIQuoteSnap 是您的事件接收器的方法,您应该复制此字符串。调用者(服务器)保留对structQuoteSnap 结构及其所有字段的所有权。通过不复制bstrUpdateTime,您“窃取”了为字符串分配的内存的所有权,并在您的本地_bstr_t 智能指针变量超出范围时立即释放此内存。服务器对此一无所知,可能会继续使用bstrUpdateTime 并最终尝试释放相同的内存两次。
  • 是的,OnSTIQuoteSnap 是我的事件接收器的一种方法。非常感谢您的解释! :)

标签: c++ com crash access-violation bstr


【解决方案1】:

OnSTIQuoteSnap 方法属于事件接收器,并被服务器回调,正如我们在 cmets 中阐明的那样。因此,服务器(作为调用者)保持对structQuoteSnap 结构及其所有字段的所有权。 updateTime 是一个本地智能指针变量,应该复制字符串 (structQuoteSnap.bstrUpdateTime),但它没有(因为 false 被传递给它的构造函数),所以它接管了 BSTR 的内存.只要updateTime 超出范围,就会释放此内存。服务器对此一无所知,可能会继续使用bstrUpdateTime,最终可能会尝试两次释放相同的内存。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-06
    • 2013-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多