【问题标题】:When to use SafeArrayAccessData to lock a SAFEARRAY何时使用 SafeArrayAccessData 锁定 SAFEARRAY
【发布时间】:2013-06-18 05:20:48
【问题描述】:

我有一个问题,即何时需要使用 SafeArrayAccessData 来锁定由托管代码传递的 SAFEARRAY。 这是我们的代码。 VARIANT 由托管代码传递,带有一个字符串数组。在代码审查期间,有人建议使用 SafeArrayAccessData/SafeArrayUnAccessData。但他不确定为什么以及有什么好处。你能分享一些你的经验吗?谢谢!

STDMETHODIMP Base::Method1(VARIANT values, VARIANT_BOOL result)
{
    CComSafeArray<BSTR> ids;
    ids.Attach(values.parray);

    unsigned int size = ids.GetCount();
    for(unsigned int i = 0; i < size; ++i)
    {
    // use ids[i] here
    }
    // ...
}

【问题讨论】:

    标签: c++ com variant safearray


    【解决方案1】:

    嗯,总是 :) 你需要它来获取对数组内容的引用。

    但是您使用了一个友好的 C++ 包装类。 CComSafeArray 模板已经为您执行此操作,因此您不应该提供帮助。它在 Attach() 方法中使用 SafeArrayLock(),该方法也像 SafeArrayAccessData() 一样返回指向数组内容的指针。并使用其析构函数自动解锁,它在您的方法结束时运行。以其他方式锁定可确保数组访问是线程安全的,并且在您访问它时不能被删除。在您现有的代码中几乎没有这种危险,但这完全符合自动化的“安全胜于遗憾”原则。

    【讨论】:

    • 谢谢!你说,我的代码比使用 SafeArrayAccessData 危险小。你的意思是后者是线程安全的实现吗?
    • 我还有一个问题?作为自动化的新手,我想知道当我将这个数组从管理代码传递到本机时,发生了什么?谁分配了 VARIANT 形式参数的内存,谁复制了数据,谁释放了它?你也可以给个提示吗?谢谢!
    • 将数组编组为 SAFEARRAY 是 CLR 的工作。它存储在 COM 互操作堆 (CoTaskMemAlloc) 中。它会在调用后销毁数组,所以如果你想保留它,你需要复制数组数据。不知道如果你保持锁定会发生什么,我认为这会死锁。
    • 致汉斯和所有其他专家:我认为没有必要锁定或解锁,但绝对有必要在ids 超出范围之前调用ids.Detach(),否则ids析构函数会破坏它不允许这样做的values.parray
    猜你喜欢
    • 2012-08-03
    • 2013-12-10
    • 1970-01-01
    • 2014-05-14
    • 2016-01-17
    • 2011-02-16
    • 1970-01-01
    • 2019-06-28
    • 1970-01-01
    相关资源
    最近更新 更多