0

下面的代码工作得很好,感谢您使用一个 COM 客户端,但使用新客户端(同一软件的更新版本)string_array_to_bstr_safearray_variant会引发访问冲突,一切都死了。

谁能告诉我我是否做错了我以前逃避的事情..?我没有正确分配内存吗?

#include "comutil.h"

void string_array_to_bstr_safearray_variant(long arraylength,char ** in_array,VARIANT *out_variant)
{
    CComSafeArray<BSTR> out_array;
    ATLENSURE_SUCCEEDED(out_array.Create(arraylength));
    for (int i=0;i<arraylength;i++)
        ATLENSURE_SUCCEEDED(out_array.SetAt(i,_com_util::ConvertStringToBSTR(in_array[i])));
    CComVariant ccv(out_array);
    HRESULT hr = ccv.Detach(out_variant);
    ATLENSURE_SUCCEEDED(hr);
}

//names: output parameter to contain variant holding safearray of bstrs
STDMETHODIMP CCalculation::get_output_shortnames(VARIANT* names)
{
    char** names_array = calc_get_short_output_names(calc); //this works fine
    string_array_to_bstr_safearray_variant(output_length,names_array,names); //this fails before returning
    return S_OK;
}

编辑:调试器信息

如果没有调试器,我会遇到访问冲突。

使用调试器单步执行此代码似乎可以工作。 output_length设置正确;out_array被正确创建和填充out_variant,据我所知,通过变量观察也是如此。但是,COM 客户端仍然失败,说"lisp value has no coercion to VARIANT with this type: #<safearray...>"(这很奇怪,因为客户端的先前版本解释返回值就好了)。然后它崩溃并抱怨它的内存不足。

在调试器中运行代码,但让它运行而不是单步执行,它在 的构造函数中失败CComVariant,抱怨由于内部调用SafeArrayCopy失败而引发了无效参数。

编辑:在最近的另一个步骤中,它在循环中失败了,所以问题可能出在@terriblememory 所暗示的 CComSafeArray 上?

4

2 回答 2

1

CComSafeArray 的文档实际上并没有说它支持 BSTR。BSTR 的功能标志是否在底层 SAFEARRAY 中设置?(这不是一个真正的答案,但我没有业力来评论,对不起!)

于 2012-05-09T02:03:36.150 回答
1

好吧,我终于找到了答案!问题中发布的代码是正确的。早期的代码导致未定义的行为:

STDMETHODIMP CCalculation::configure(VARIANT radii) // radii contains a safearray of doubles
{
CComSafeArray<double> radii_sa;
radii_sa.Attach(radii.parray);
ULONG num_radii = radii_sa.GetCount();

//unpack radii array into c-style array
double *radii_array = new double[num_radii];
for (long i=0;i<num_radii;i++)
radii_array[i] = radii_sa.GetAt(i);

//...do something with radii_array...

delete[] radii_array;

return S_OK;
}

你发现故意的错误了吗?COM 规则说半径属于客户端,而不是我的 dll。通过附加到它然后让包装器超出范围,我正在释放安全数组。通过在 return 语句之前添加这个来修复:

radii_sa.Detach();
于 2012-06-21T13:31:59.523 回答