「複数のOptional引数」を持つCOMのメソッドをC++で実装するには?


セニョモン  2009-04-19 07:07:13  No: 70016

C++でCOMを使用してExcel操作を実装しようとしています。
(http://support.microsoft.com/?scid=kb;ja;216686&spid=2512&sid=97)

そこで、ファイルを開くOpenメソッドを実装する際にReadOnly引数の第3引数までを指定すると、Invokeでエラーになってしまいます。
(エラーコード:0x800a03ec)

---------------------------------------------------------
VARIANT fileName, updateLinks, readOnly;

VariantClear(&fileName);
VariantClear(&updateLinks);
VariantClear(&readOnly);

fileName.vt         = VT_BSTR;
fileName.bstrVal    = ::SysAllocString(mFilePath);
updateLinks.vt      = VT_BOOL;
updateLinks.boolVal = false;
readOnly.vt         = VT_BOOL;
readOnly.boolVal    = true;

AutoWrap(DISPATCH_METHOD, &result, pBooks, L"Open", 3, fileName, updateLinks, readOnly);

::SysFreeString(fileName.bstrVal);
---------------------------------------------------------------

AutoWrap関数の第5引数を1にする(Openメソッドに渡す実引数の個数を1つだけにする)と正常にファイルを開けるのですが、これではreadOnlyで開くことはできません。

Openメソッドのように複数のOptional引数を持つCOMメソッドを特定の引数までを渡す場合、上記のコードでは問題があるのでしょうか?


オショウ  2009-04-19 07:47:22  No: 70017

http://support.microsoft.com/kb/238393/ja

この例だと、AutoWrapに該当するpDisp->Invokeの部分の変数の
与え方が違いますが・・・

※  私は実際にC++でCOMはやっていませんが、MFCでは問題なく
    使っていたもので。
    的外れならすいません・・・

ご検討下さい。

以上。


subaru  2009-04-20 02:01:39  No: 70018

>VARIANT fileName, updateLinks, readOnly;
>
>VariantClear(&fileName);
>VariantClear(&updateLinks);
>VariantClear(&readOnly);

VariantClearは変数の状態によりメモリの解放を行うので未初期化の変数に使うのは危険です。
VARIANT変数の初期化にはVariantClearではなく、VariantInitを使用してください。

>::SysFreeString(fileName.bstrVal);

こちらはVariantClearをfileNameに対して行えばメモリは解放されるので、
上記SysFreeStringは呼ぶ必要はありません。
(VariantClearで開放しない場合は必要です)

>AutoWrap関数の第5引数を1にする(Openメソッドに渡す実引数の個数を1つだけにする)と正常にファイルを開けるのですが、これではreadOnlyで開くことはできません。
>
>Openメソッドのように複数のOptional引数を持つCOMメソッドを特定の引数までを渡す場合、上記のコードでは問題があるのでしょうか?

IDispatch::Invokeに渡すパラメーターの配列は引数の逆順に作る必要がありますが
AutoWrap関数の内容を見る限り、特に順序の入れ替えなどは行ってないようです。
>AutoWrap(DISPATCH_METHOD, &result, pBooks, L"Open", 3, fileName, updateLinks, readOnly);
  ↓
AutoWrap(DISPATCH_METHOD, &result, pBooks, L"Open", 3, readOnly, updateLinks, fileName);
に書き換えてみてもダメでしょうか?


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加