【发布时间】: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->GetString(&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