是否释放记录集返回的 BSTR

Posted

技术标签:

【中文标题】是否释放记录集返回的 BSTR【英文标题】:Release BSTR returned from recordset or not 【发布时间】:2018-09-07 06:11:32 【问题描述】:

这里有一些 ADODB 代码从记录集中检索 BSTR,但我不确定 BSTR 是否应该与 SysFreeString 一起发布。现在它是并且它似乎正在工作,但你应该自己做吗?

    BSTR bstr = m_pRecordset->Fields->GetItem ( field )->Value.bstrVal;

    int len = SysStringLen(bstr);

    while (len > 0 && iswspace(bstr[len-1])) len--;

    BSTR newstr = SysAllocStringLen(bstr, len);

    SysFreeString(bstr);
    SysFreeString(newstr);

【问题讨论】:

【参考方案1】:

您的代码错误。 m_pRecordset->Fields->GetItem ( field )->ValueVARIANT 返回为 _variant_t

您应该将对象保存在临时变量中,访问数据,然后析构函数将完成剩下的工作。

_variant_t val = m_pRecordset->Fields->GetItem ( field )->Value;

int len = SysStringLen(val.bstrVal);

while (len > 0 && iswspace(bstr[len-1])) len--;

BSTR newstr = SysAllocStringLen(val.bstrVal, len);
...
SysFreeString(newstr);

See sample here in the MSDN.

另外应该提到的是,最好使用CComBSTR_bstr_t 而不是BSTR。

【讨论】:

当您使用由 Visual C++ 生成的代码而不是原始 COM 接口时,您将不再使用 BSTR 或 VARIANT,而始终使用 _bstr_t 和 _variant_t,并且(几乎)忘记释放内存,因为如您所知,它们是智能包装类。因此,在您的代码中,我不会使用 BSTR,也不会使用 SysFreeString。此外,您的链接指向德国文档 :-) @sim:我也建议使用_bstr_t,虽然我不确定你会如何在这里使用它。虽然它有一个带有variant_t& 的c'tor,但构造的对象是严格不可变的,并且似乎没有任何方法可以在另一个_bstr_t/wchar_t[]/ 的子范围内构造_bstr_t BSTR. @IInspectable - 我只是在谈论 newstr 变量,它可能是 _bstr_t 而不是 BSTR 你是对的。我只是按照用户编写的代码使用... _bstr_t 在这里也好得多! 在这里使用CComBSTR 可能更合适,因为它提供了一个带有显式长度参数的c'tor。

以上是关于是否释放记录集返回的 BSTR的主要内容,如果未能解决你的问题,请参考以下文章

返回带有零而不是空值的 Access 记录集

访问 VBA。检测记录集条目是不是会溢出

使用 DAO 在 Ms Access 中打开记录集时使用 With...End

游标是不是将 SELECT 结果记录集存储在内存中?

为啥 ADO 记录集返回的记录比基础 Access 查询多

PHP 类可以返回记录集吗