You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从VT_DISPATCH类型的SAFEARRAY中获取有效IDispatch指针?

问题原因与解决方案

你的代码崩溃的核心原因是类型转换错误:当SAFEARRAY的元素类型为VT_DISPATCH时,每个元素存储的是IDispatch*指针,而SafeArrayPtrOfIndex返回的pData是指向该元素的指针(即IDispatch**类型)。你直接将pData强制转换为IDispatch*,相当于对指针的内存地址调用AddRef,而非真正的IDispatch对象,必然触发访问异常。

正确示例代码

if (vtS == VT_DISPATCH) {
    IDispatch* iDisp = NULL;
    IDispatch** ppDisp = NULL;
    HRESULT ret = S_OK;

    // 假设idx是一维数组的有效索引(指向LONG类型的索引变量)
    if (idx) {
        // 将pData转为IDispatch**类型,而非直接转IDispatch*
        ret = SafeArrayPtrOfIndex(SA, idx, reinterpret_cast<void**>(&ppDisp));
        if (FAILED(ret)) {
            goto CleanUp;
        }
        // 解引用得到真正的IDispatch指针
        iDisp = *ppDisp;
    } else {
        // 可选:若取一维数组第一个元素,也可使用SafeArrayGetElement
        LONG firstIdx = 0;
        ret = SafeArrayGetElement(SA, &firstIdx, &iDisp);
        if (FAILED(ret)) {
            goto CleanUp;
        }
    }

    // 必须先检查指针非空,再调用AddRef
    if (iDisp) {
        iDisp->AddRef();
        pVGet->vt = VT_DISPATCH;
        pVGet->pdispVal = iDisp;
    } else {
        // 处理空指针情况,避免无效赋值
        pVGet->vt = VT_NULL;
    }

CleanUp:
    // 无需手动解锁数组,SafeArrayPtrOfIndex内部已自动处理锁定/解锁
    // 若有其他资源需释放,在此添加逻辑
}

关键注意事项

  • 类型匹配:SafeArrayPtrOfIndex返回的是元素的地址,需根据SAFEARRAY元素类型匹配指针类型(VT_DISPATCH对应IDispatch**)。
  • 空指针检查:调用AddRef前必须确认iDisp不为NULL,否则会触发空指针访问异常。
  • 引用计数管理:SAFEARRAY中的IDispatch*指针不会自动增加引用计数,取出后必须调用AddRef确保对象不会被提前释放;后续不再使用pVGet->pdispVal时,需调用Release释放引用。

内容的提问来源于stack exchange,提问作者René Rössler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 23:05:11