使用 ::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。更多平台依赖性? 的相关文章

  • 不知从何而来的用户断点

    我正在调试 MS VC 6 0 中的一些代码 出于某种原因 在我试图删除一些动态分配的内存的某个时刻 它崩溃了 我收到一个弹出消息框 上面写着 从代码中调用的用户断点等等 然后弹出 反汇编 窗口 我看 memory address int
  • 为什么我不能执行 std::map.begin() + 1?

    我有一个std map 我想从第二个条目开始迭代 我可以解决这个问题 但我对为什么 明显 语法无法编译感到困惑 该错误消息没有帮助 因为它指的是std string 我在这里没有使用它 这是一些代码 Suppose I have some
  • 是否可以通过VC++属性表更改工作目录?

    我计划创建一些相关的 C 项目 这些项目都有几个共同的设置 输出路径 exe 命名约定 中间目录等 并且我已经成功设置了除工作之外的大部分我需要的设置 目录 默认情况下它设置为 ProjectDir 但我希望将其设置为 OutDir 并且我
  • *.tlb 文件在运行时使用过吗?

    我正在开发一个通过 COM 互操作公开一些 NET API 的产品 作为构建的一部分 我们为所有此类程序集生成 tlb 文件 并将它们作为单独 SDK 包的一部分提供 我们的客户可以在我们的产品之上安装 SDK 并创建使用我们的 COM A
  • 在结构内创建结构

    我正在努力将在 Visual c 6 0 中创建的旧 C windows 驱动程序项目导入到 Visual Studio 2012 中 定义结构的方式导致 vs2012 中出现错误 typedef struct LINK Link HAND
  • CLSIDFromProgID 成功但 CreateInstace 失败!为什么?

    我正在尝试创建 COM 对象的实例 我有实现该接口的类名 并使用 CLSIDFromProgID 获取 CLSID 因此 自从我获得 CLSID 以来 我想从现在开始一切都会好起来的 但是 当我调用 CreateInstance 并传入 C
  • 使用 Visual Studio Express 2010 表单应用程序进行 C++ 多线程处理

    我正在开发一个 Windows 窗体应用程序 它连接到一个硬件 获取大量数据 1 GSample 秒 对其进行处理 然后单击按钮将其输出到屏幕上 我现在尝试在一个可以随时启动 停止的循环中自动化该过程 以便我可以在调整采集硬件的输入的同时对
  • 如何禁用导入库的生成?

    我正在 Visual Studio 中创建一个 COM DLL 链接器为 DLL 生成导入库 我不需要导入库 有什么办法告诉链接器不要生成它吗 九年后 这可能对 OP 没有用 但可能对其他寻求解决方案的人有用 LINK EXE 支持 NOI
  • ATL创建的COM接口继承IDispatch但后期绑定不起作用

    这是我的 IDL 文件 IFrame 是一个双接口 同时继承了 IDispatch 和 IUnknown object uuid C5AD0517 37FC 479C 9C7A A063B17E4A2E dual nonextensible
  • 在静态断言和运行时错误之间自动选择

    我有一个执行除法并检查对齐的宏 define BYTES TO WORDS x CHECK ALIGNMENT x 2 x 2 我想实施CHECK ALIGNMENT作为一个总是返回 1 的宏 并且如果满足以下条件则触发错误x不除以 2 宏
  • GetActiveObject() 与 GetObject() -- MK_E_UNAVAILABLE 错误

    All 我在将一些 VBA 代码转换为 C 时遇到一些问题 我们有一个充当本地 COM 服务器的第 3 方应用程序 在我们使用的VBA代码中获取对象 获取对现有对象的引用 e g Set appHandle GetObject ProgId
  • C# 暴露给 COM - 接口继承

    假设我有一个实现 IBaseClass 的类 BaseClass 然后我有一个继承IBaseClass的接口IClass 然后我有一个名为 class 的类 它实现了 IClass 例如 ComVisible true InterfaceT
  • Visual Studio 2017 中的“onecore”文件夹

    在Visual Studio 2017 RTM VC Tools MSVC 14 10 25017 lib文件夹中 有一个名为 onecore 的文件夹 里面有x64 x86和arm的文件夹 每个文件夹都包含一些VC Tools中已经存在的
  • 有效地调用非托管方法,将非托管对象作为托管代码的参数

    我有以下场景 托管代码将初始化类的许多对象 该类是非托管结构的包装器 为此我可以采用两种方法 一种是拥有一个托管类包装器 它只有一个指向非托管对象的指针 另一种是拥有一个成熟的托管类 并在需要调用非托管方法时创建非托管对象 我已经提供了以下
  • 编译过程

    谁能解释一下编译是如何工作的 我似乎无法弄清楚编译是如何工作的 更具体地说 这是一个例子 我正在尝试在 MSVC 6 中编写一些代码来加载 Lua 状态 我已经 设置库的附加目录并将文件包含到正确的目录中 使用 extern C 因为 Lu
  • COM 互操作注册

    我有一个正在暴露的 NET 程序集COM http en wikipedia org wiki Component Object Model 该程序集有两个公共接口和一个公共类 当我构建程序集时 我收到此警告 AssemblyName dl
  • 如何更新 C++ dll 而无需将 exe 与 lib 文件重新链接?

    首先 我指的是 Windows 环境和 VC 编译器 我想要做的是重建 Vc dll 并保持与已链接到 lib 的 exe 的兼容性 而无需重建 exe 或使用 LoadLibrary 动态加载 dll 换句话说 有没有办法向 dll 添加
  • 如何使用 microsoft Visual C++ 编写调用 JNI 的代码 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我如何编写C代码microsoft
  • 为什么我的 COM 对象不显示组件服务中的方法?

    我正在尝试创建一个 COM 对象并将其注册到 COM 下 一切似乎都很顺利 但是当我查看组件服务并深入了解时 控制台根目录 组件服务 电脑 我的电脑 COM 应用程序 测试通讯 组件 TestCom Com MyCom 接口 MyCom 方
  • 从经典 ASP 调用 .Net C# DLL 方法

    我正在开发一个经典的 asp 项目 该项目需要将字符串发送到 DLL DLL 会将其序列化并发送到 Zebra 热敏打印机 我已经构建了我的 DLL 并使用它注册了regasm其次是 代码库这使得 IIS 能够识别它 虽然我可以设置我的对象

随机推荐

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

    我见过其他问题 例如硬件键盘事件 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