【问题标题】:How to release a SAFEARRAY within another SAFEARRAY如何在另一个 SAFEARRAY 中释放 SAFEARRAY
【发布时间】:2014-05-14 20:11:05
【问题描述】:

我正在通过 COM 接口(使用 .NET Interop)使用 MFC/C++ 中的 .NET 组件。该接口包含包含数组的结构(导致 COM 中的 SAFEARRAYS)。

我无法以正确的方式释放 SAFEARRAY。运行应用程序时,应用程序将在第二个 SafeArrayDestroy 处崩溃。那么,在删除外部 SAFAARRAY 时,内部 SAFEARRAY 会被删除吗? 还有其他想法吗?

谢谢!

C# 界面如下所示:

public struct structVersionCondition
{
    public Int32 m_val;
}
public struct structVersion
{
    public structVersionCondition[] m_VersionConditions;
}
public struct structVersions
{
    public structVersion[] m_Version;
}

public interface TextStore_Interface
{
    [DispId(1)]
    bool GetVersionRef(out structVersions versions);
}

从 MFC/C++ 调用生成的 COM IF,如下所示:

m_pIF->GetVersionRef(&ver, &retVal);
SafeArrayAccessData(ver.m_Version, (void**)&pValsOuter);
//..Get Lower and Upper bound calculate number of elements
for (int i=0; i<elem_no; ++i){
    SafeArrayAccessData(pValsOuter[i].m_VersionConditions, (void**)&pValsInner);
    //operate on the structVersionCondition[] SAFEARRAY trough pValsInner
    SafeArrayUnaccessData(pValsOuter[i].m_VersionConditions);
    SafeArrayDestroy(pValsOuter[i].m_VersionConditions);
}
SafeArrayUnaccessData(ver.m_Version);
SafeArrayDestroy(ver.m_Version); //Exception is thrown here!

问候 约翰

【问题讨论】:

  • 您破坏了 m_VersionConditions 数组,但忘记将指针设置为 NULL。所以销毁 m_Version 会再次尝试销毁内部数组。卡布姆。
  • 在调用 SafeArrayDestroy 后将 SAFEARRAY 指针设置为 NULL,似乎可以解决问题!非常感谢......

标签: .net com mfc interop safearray


【解决方案1】:

据我所知,我理解 SafeArrayDestroy 函数,您不负责释放存储在 SafeArray 中的数组。

SafeArrayDestroy 释放与其存储的成员相关的所有内存。它就像存储在 SafeArray 中的 VARIANT。 VariantClear 被调用。 IDispatch 指针也被释放。

SafeAray 以正确的方式处理所有 COM 类型。

但事实上:我从未尝试过你构造。当我将数据嵌套在 SafeArray 中时,我总是使用 VARIANT。

文档不是很清楚:SafeArrayDestroy

销毁现有的数组描述符和数组中的所有数据 大批。如果对象存储在数组中,则在每个对象上调用 Release 数组中的对象。

变体的安全数组将调用 VariantClear 函数 BSTR 的每个成员和安全数组都将具有 SysFreeString 对每个元素调用的函数。 IRecordInfo::RecordClear 将是 调用以释放对象引用和记录的其他值 无需释放记录。

【讨论】:

  • 是的,文档可以解释。 Hans Passant 提供的建议起到了作用。但是,如果外部 SAFEARRAY 看到内部 SAFEARRAY 为 NULL,它似乎不会尝试释放内部 SAFEARRAY,但这可能意味着如果内部 SAFEARRAY 为 NULL,外部 SAFEARRAY 将释放内部 SAFEARRAY?!无论如何,知道我自己亲自发布了所有 SAFEARRAY,我感觉好多了!
猜你喜欢
  • 2012-08-03
  • 1970-01-01
  • 2019-06-28
  • 2016-02-24
  • 1970-01-01
  • 2014-05-15
  • 1970-01-01
  • 2019-06-18
  • 1970-01-01
相关资源
最近更新 更多