使用 ::SysFreeString() 释放 BSTR。更多平台依赖性?

2024-03-18

我正在编写一个 COM 服务器,它有很多接口和方法。大多数方法都将 BSTR 作为参数并作为用于返回的本地参数。一个片段看起来像

更新5:

真正的代码。它根据数据库的特定条件从一堆数据中获取数据以填充对象数组。

STDMETHODIMP CApplication::GetAllAddressByName(BSTR bstrParamName, VARIANT *vAdddresses)
{
    AFX_MANAGE_STATE(AfxGetStaticModuleState())

//check the Database server connection

COleSafeArray saAddress;
HRESULT hr;

// Prepare the SQL Strings dan Query the DB

long lRecCount = table.GetRecordCount();

 if (lRecCount > 0)
 {
    //create one dimension safe array for putting  details
    saAddress.CreateOneDim(VT_DISPATCH,lRecCount);

    IAddress *pIAddress = NULL; 
    //retrieve details 
    for(long iRet = table.MoveFirst(),iCount=0; !iRet; iRet = table.MoveNext(),iCount++)
    {
        CComObject<CAddress> *pAddress;
        hr = CComObject<CAddress>::CreateInstance(&pAddress);
        if (SUCCEEDED(hr))
        {   
            BSTR bstrStreet = ::SysAllocString(table.m_pRecordData->Street);
            pAddress->put_StreetName(bstrStreet);

            BSTR bstrCity = ::SysAllocString(table.m_pRecordData->City);
            pAddress->put_CityName(bstrCity);
        }
        hr = pAddress->QueryInterface(IID_IAddress, (void**)&pIAddress);
        if(SUCCEEDED(hr)) 
        {
            saAddress.PutElement(&iCount,pIAddress); 
        }
    }
    *vAdddresses=saAddress.Detach(); 
}
table.Close(); 
return S_OK;
}


STDMETHODIMP CAddress::put_CityName(BSTR bstrCityName)
{
    AFX_MANAGE_STATE(AfxGetStaticModuleState())
    // m_sCityName is of CComBSTR Type
    m_sCityName.Empty();//free the old string 
    m_sCityName = ::SysAllocString(bstrCityName);//create the memory for the new string
    return S_OK;
}

问题出在内存释放部分。该代码在任何 Win XP 机器上都运行得很好,但是当涉及到 WIN2K8 R2 和 WIN7 时,代码崩溃并指出 ::SysFreeString() 是罪魁祸首。 MSDN 不足以提供解决方案。

任何人都可以帮助找到正确的解决方案吗?

预先非常感谢:)

更新1:

我已尝试按照建议使用 CComBSTR 代替原始 BSTR,使用直接 CString 进行初始化并排除 SysFreeString()。但对于我来说,在超出范围时,系统正在调用 SysFreeString(),这再次导致崩溃:(

更新2:使用相同的 CComBSTR 我尝试使用 SysAllocString() 进行分配,问题仍然相同:(

更新3:我厌倦了所有的选择,平静地我脑子里只有一个问题

是否有必要通过 SysFreeString() 释放 BSTR 使用 SysAllocString()/string.AllocSysString() 分配?

更新4:我错过了提供有关崩溃的信息。当我尝试调试 COM 服务器崩溃并显示错误时

“可能的堆损坏”

。请帮助我离开这里..:(


// Now All Things are packed in to the Object
obj.Name = bstrName;
obj.Name2 = bstrname2;

我不太明白你所说的东西被打包是什么意思,因为你只是复制指向字符串的指针,而当你调用 SysFreeString obj.Name 和 obj.Name2 时,它将指向无效的内存块。尽管此代码不安全,但看起来问题的根源是 CFoo 类。您应该向我们展示您的代码的更多详细信息

我建议您使用 CComBSTR 类,它将负责释放内存。

UPDATE

#include <atlbase.h>
using namespace ATL;
...
{
    CComBSTR bstrname(_T("Some Name")); 
    CComBSTR bstrname2(_T("Another Name"));
    // Here one may work with these variables if needed
    ...
    // Copy the local values to the Obj's member Variable 
    bstrname.Copy(&obj.Name); 
    bstrname2.Copy(&obj.Name2);
}

UPDATE2首先,应该在该块中使用 SysFreeString 释放 bstrCity 和 bstrStreetName 或使用 CComBSTR 代替:

if (SUCCEEDED(hr))
{   
    BSTR bstrStreet = ::SysAllocString(table.m_pRecordData->Street);
    pAddress->put_StreetName(bstrStreet);

    BSTR bstrCity = ::SysAllocString(table.m_pRecordData->City);
    pAddress->put_CityName(bstrCity);

    // SysFreeString(bstrStreet)
    // SysFreeString(bstrCity)
} 

考虑放大循环条件 !iRet,其中 iCount

for(...; !iRet /* && (iCount < lRecCount) */; ...)

也在这里:

m_sCityName = ::SysAllocString(bstrCityName);

您分配内存但从未释放它,因为 CComBSTR& 运算符 = (OLESTR ..) 本身会分配新的存储空间。应该重写如下:

m_sCityName = bstrCityName;

其他一切对我来说看起来都不错

UPDATE3嗯,堆损坏通常是在分配的内存块之外写入某些值的结果。假设您分配一个长度为 5 的数组并将一些值放入第 6 个位置

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 ::SysFreeString() 释放 BSTR。更多平台依赖性? 的相关文章

  • IRunningObjectTable.Register 始终将 pdwRegister 设置为 65536,这是一个无效值

    我在用着IRunningObjectTable Register and IRunningObjectTable Revoke如图所示this http www codeproject com KB COM ROTStuff aspx ms
  • 如何禁用 C++ 宏中的警告

    在 Visual C 中 您可以使用 pragma 暂时禁用警告 pragma warning suppress 4307 如何禁用宏内的警告 例如 当我导致如下所示的 积分常量溢出 警告时 define TIMES A MILLION x
  • C# 如何获取 COM 接口的实例

    我做了很多谷歌搜索 试图找到获取 COM 接口实例的标准方法 微软在他们的文章中提供了一个例子COM 互操作第 1 部分 客户端教程 https msdn microsoft com en us library aa645736 v vs
  • _CrtDumpMemoryLeaks( ) == 1 在第一行代码上?

    我正在开发一个 MFC Visual C 项目 据我了解MSDN http msdn microsoft com en us library d41t22sb 28v VS 100 29 aspx CrtDumpMemoryLeaks 应该
  • 哪个是对的? catch (_com_error e) 还是 catch (_com_error& e)?

    我应该使用哪一个 catch com error e or catch com error e 第二 这是我试图引用萨特的话 按值抛出 按引用捕获 学会catch正确 按值 而不是指针 抛出异常 通过引用捕获它们 通常是const 这是组合
  • C++ 中的编译器指令重新排序优化(以及阻碍它们的因素)

    我已将代码缩减为以下内容 这在保留我感兴趣的编译器输出的同时 尽可能简单 void foo const uint64 t used uint64 t ar 100 for int i 0 i lt 100 i ar i some globa
  • 编译器优化导致性能下降

    我有一个奇怪的问题 我有以下代码 template
  • switch 在 Visual C++ 中如何编译?它的优化程度和速度如何?

    我发现我只能在 C 中使用数值switch陈述 我认为它和一堆更深层的区别if else s 因此我问自己 如何switch与 不同if elseif elseif在运行速度 编译时优化和一般编译方面 我这里主要说的是MSVC 开关通常被编
  • 在 Visual Studio 中模拟 GCC 的 __builtin_unreachable?

    我见过this https stackoverflow com q 6031819 10147399关于模仿的问题 builtin unreachable在旧版本的 GCC 中 我的问题正是如此 但针对的是 Visual Studio 20
  • 使用带有 MSVC 2015 编译器的 QT Creator 5.8

    我是新来的C 和编程 我正在尝试做一个小项目 使用Qt and Qt Creator 我当时用的是MinGW compiler 但对于这个项目 我需要与MSVC compiler 因为我需要使用QtWebEngineWidgets I ha
  • uninitialized_copy memcpy/memmove 优化

    我最近开始研究 MSVC 实现中的 STL 那里有一些不错的技巧 但是我不知道为什么使用以下标准 The std uninitialized copy被优化为一个简单的memcpy memmove如果满足某些条件 据我了解 输入范围可以是m
  • C++ win32设置光标位置

    我知道要使用哪个功能 但我无法让它正常工作 我用了SetCursorPos 唯一的问题是它将光标设置为屏幕坐标而不是窗口坐标 我也尝试过ScreenToClient 但它并没有起作用 这是我的代码 pt x 113 pt y 280 Scr
  • 我可以在 C++ 结构上实现 .ToString() 以进行调试吗?

    在 C 中 如果我定义了一个结构体 我还可以重写 ToString 然后 当我进行调试并添加监视或将鼠标悬停在结构的实例上时 工具提示将是计算出的 ToString 而不是结构的类型名称 我可以在 C 和 或 C CLI 中以某种方式做到这
  • 如何使用 ClickOnce 安装 COM

    我已经安装了使用 TeeChart ActiveX COM 使用 ClickOnce 绘制图表的组件 如果我使用 regsvr32 teechart8 ocx 手动注册 TeeChart 我的 应用程序工作正常 但我想要并且需要使用安装应用
  • 无法访问 VBA 中的 COM 公开方法

    我正在尝试在 VBA 中访问 COM 公开的方法 Problem 我看到所有默认方法 例如GetHashCode GetType and ToString 在 VBA 中但是not那些是 COM 接口的一部分并且专门编写为 COM 可见的
  • 服务器端生成的 Excel 中出现 System.Runtime.InteropServices.COMException 错误

    我们有一个 Web 应用程序 可以生成 Excel 电子表格并在服务器端运行宏 然后它通过电子邮件将它们发送给不同的人 它是传统报告风格的一部分 我们正在对其进行转换 但仍然支持我们作为 IIS 中的网站提供的新应用程序 我知道进行 Off
  • 免注册 COM - COM dll 相对于客户端 exe 的位置

    我想使用免注册 com 这样我就不必注册我的旧 com 组件 但是 我希望能够将 com dll 放在不在客户端 exe 目录中或之下的位置 例如 lib 我无法在服务器清单文件中执行此操作 因为它不允许相对或绝对路径 有谁知道是否有办法解
  • tlb 文件是否具有关联架构?

    我有一个 32 位 DLL 旨在通过 com 模型和关联的 tlb 文件进行访问 该 DLL 似乎是 x86 有没有办法从 x64 程序访问这种 DLL tlb 文件与 x86 x64 无关吗 我问这个问题是因为有些功能似乎可以工作 其他功
  • 基于 MSVC 10 范围的 for 循环

    目前 在我们正在开发的一个大型 C 项目中 我们有一堆新样式的 for 循环 如下所示 for auto value values 到目前为止 我们一直只使用 gcc 4 6 进行编译 最近 一些代码库正在移植到 Windows 一些开发人
  • 导出类时编译器错误

    我正在使用 Visual Studio 2013 但遇到了一个奇怪的问题 当我导出一个类时 它会抛出 尝试引用已删除的函数 错误 但是 当该类未导出时 它的行为会正确 让我举个例子 class Foo note the export cla

随机推荐

  • 有没有办法检测手机上是否有硬件键盘?

    我见过其他问题 例如硬件键盘事件 https stackoverflow com questions 4883168 hardware keyboard event 但Mango 没见过这个 有什么方法可以查出手机是否有硬件键盘 Use t
  • Firebase Firestore 查询得到一个结果

    我正在寻找最好的方法 1 查询单个结果 或者2 从查询中提取第一个结果 tried collection 0 and collection pop or collection shift 没有任何作用 我真的不喜欢我正在使用的代码 但它有效
  • 使用 JOGL 进行全屏摆动

    我正在尝试制作一个全屏呈现的 Swing 应用程序 遵循此处的描述http download oracle com javase tutorial extra fullscreen exclusivemode html http downl
  • 错误:没有匹配的函数可供调用

    我想在另一个类中使用另一个类的方法 但出现以下错误 问题是什么 TIA 错误 没有匹配的函数可用于调用 PositionInfo PositionInfo 这是我的代码 PositionInfo Pos double metr Pos Ge
  • 如何设置图片的大小?

    I have 飞溅 png并希望该图像全部出现在屏幕上 就像fitXY for ImageView 飞溅 png尺寸为 480x767 我必须在代码中更改什么 public class BitmapConfigView extends Li
  • PHP 中 $variable->something 的故事是什么?

    我见过这种方法被广泛使用 尤其是在 SimpleXML 中 Is this row gt unixtime 和这样做一样吗 row unixtime 这叫什么 为什么 如何使用它 使用 PHP 进行面向对象编程 https stackove
  • 使用 REST API 通过 PHP 连接到 VCenter 身份验证错误

    我按照官方 vSphere 站点中的说明从服务器和答案中获取信息这里的另一个用户 https stackoverflow com a 49324757 12013253 据我了解 首先我必须获取会话id cis id 但结果我得到 null
  • Django 模板扩展和 CSS

    我有这样的基本模板 当我刷新页面时 此文本会记录在日志中 01 Dec 2011 18 22 00 GET search HTTP 1 1 200 2760 01 Dec 2011 18 22 00 GET static style css
  • 关闭并打开新窗口后,SSH 密钥在 git bash 上不起作用

    使用以下链接创建 ssh 密钥 https help github com articles generate a new ssh key and adding it to the ssh agent https help github c
  • 逻辑右移、算术右移、循环右移的区别

    我一直在阅读经典的 黑客之乐 但我很难理解逻辑右移 算术右移和右旋转之间的区别 如果疑问看起来太简单 请原谅 首先记住机器字的大小是固定的 说 4 您的输入是 a b c d 然后将所有内容向左推一位即可得到 b c d X 问题 X 应该
  • 在javascript中调用java方法[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我正在尝试在 javascript 中调用 java 方法 java类驻留在服务器端 示例 Java 代码是 public class
  • 按类前缀定位元素

    假设我有以下元素 div class home div class tab231891230 div div class tab121232441 div div class tab123134545 div div 如何使用 jQuery
  • 查找二维 numpy 数组中的共同元素

    如果我有两个 或更多 二维数组 如何在给定行号的情况下仅获取数组之间的公共元素 例如 我有以下格式的数组 time position velocity acceleration 我想让两个数组只具有相同的时间元素 所以第 0 行 我可以使用
  • 使用 wmi win32 类检查可用端口?

    我正在使用 inno setup 来制作安装文件 它需要提取本地 IP 地址 我可以通过查询 Win32 NetworkAdapterConfiguration 来完成 并检查特定端口是否打开以供软件运行 我目前正在寻找答案 我意识到 WM
  • 将我的 ASP.NET MVC 页面另存为 pdf

    如何将 ASP NET MVC 页面保存为 PDF 有第三方库可以为您提供非常好的保真度 我写这个帖子 http blog muhimbi com 2010 08 convert sharepoint html pages to pdf h
  • 程序集 - 无法设置断点 lldb

    我用这些选项组装了nasm O0 g f macho64但 lldb 抱怨 无法将断点解析到任何实际位置 当我尝试在文件中的行号处设置任何断点时 我已经开始尝试学习 OS X 的 64 位汇编 但到目前为止这确实是一个挑战 似乎几乎没有任何
  • Python绘图图像保存错误

    我是Python新手 我已经使用 Django 编写了 Web 服务来将图像保存在服务器中 我正在尝试使用下面的代码将绘图保存为图像 并且它可以正常工作 3 次 之后 Python 会抛出错误 如何解决这个问题 Exception igno
  • 我可以像这样使用 try-catch-finally 吗?

    我在用着try catch多年来 但我从未学会如何以及何时使用finally 因为我从来不明白这一点finally 我读过坏书 我想问你关于使用finally就我而言 我的代码示例应该解释一切 s c MyClassForFileHandl
  • Flyspell 无法在 emacs 中加载 LaTeX 文件

    下列的这个网页 http www sop inria fr members Manuel Serrano flyspell flyspell html 我编辑了 emacs 文件并添加了以下行 add hook LaTeX mode hoo
  • 使用 ::SysFreeString() 释放 BSTR。更多平台依赖性?

    我正在编写一个 COM 服务器 它有很多接口和方法 大多数方法都将 BSTR 作为参数并作为用于返回的本地参数 一个片段看起来像 更新5 真正的代码 它根据数据库的特定条件从一堆数据中获取数据以填充对象数组 STDMETHODIMP CAp