次のコードは、COMクライアント1台につき、ありがとうございましたが、新しいクライアント(同じソフトウェアの更新版)string_array_to_bstr_safearray_variant
がアクセス違反をスローし、すべてが死にます。COM:BSTRのSafeArrayを作成するアクセス違反
誰かが私が前に逃げていた何か間違っていることを教えてもらえますか?メモリを正しく割り当てることができませんか?
#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_variant
です。しかし、COMクライアントはまだ失敗し、"lisp value has no coercion to VARIANT with this type: #<safearray...>"
と言っています(以前のバージョンのクライアントは戻り値をうまく解釈するので、これは奇妙です)。その後、それはメモリ不足であると不満をクラッシュします。
デバッガ内でコードを実行しているが、ステッピングではなく実行すると、への内部呼び出しが失敗したため、無効な引数がスローされ、CComVariant
のコンストラクタ内で失敗しました。
編集:別の最近のステップスルーでループに失敗しました。だから、おそらく問題は@terriblememoryが示唆するようにCComSafeArrayにありますか?
COM、SafeArrays&BSTRs ... Oh my! –
暗い雲が崩壊し、稲妻の嵐が打たれ、* output_length *変数に値が与えられました。それは端に少し鮮明であることにバインドされています。 *配列長*も返さない配列を返す関数を記述しないでください。彼らは基本的に危険です。ベクトル<>は明白な選択です。 –
Lol :)はい、 'output_length'はクラスメンバーで、' get_output_shortnames() 'が呼び出されるまでに有効です。 'calc_get_short_output_names'はCインタフェースです。それはバグではありません。 –