0

COM オブジェクトのメソッドを呼び出す for ループでメソッドを呼び出しています (Inventor 2012)。

以前のコードは次のとおりです。

foreach (var occ in occurrences)
{
    // [...]
    SomeMethod(occ);
    // [...]

リファクタリング時に、メソッド呼び出しをインライン化することにしました。

foreach (var occ in occurrences)
{
    // [...]
    BOMQuantityTypeEnum quantityType;
    object quantity;
    occ.Definition.BOMQuantity.GetBaseQuantity(out quantityType, out quantity);
    if (quantityType ==
    // [...]
}

他に何も変更していませんが、これは失敗し始め、E_INVALIDARG がスローされました。さらに、メソッドが 2 回目に呼び出されたときにのみ失敗します。ただし、次のように変更すると、再び機能します。

    BOMQuantityTypeEnum quantityType = 0;
    object quantity = null;
    occ.Definition.BOMQuantity.GetBaseQuantity(out quantityType, out quantity);

なぜこれが起こるのでしょうか?

編集:

COM オブジェクトが前の反復の値を読み取る可能性はありますか?

署名はドキュメント (VB) に次のように記載されています。

Sub GetBaseQuantity(ByRef QuantityType As BOMQuantityTypeEnum, ByRef Quantity As [optional] VARIANT)

C#署名は間違っていますか? COM インターフェイスは自動生成されませんか?

4

1 に答える 1

0

COM オブジェクトが前の反復の値を読み取る可能性はありますか?

はい、そうです。メソッドの戻り値を除いて、COM オートメーションにはoutに相当するものはありません。どうやってrefの代わりにoutを使わなくなったのかはかなり謎です。おそらく、COM インターフェイスの宣言に使用された IDL の単なるバグです。COM オートメーションと互換性のある IDL 属性は、[in]、[in,out]、および [out,retval] のみです。

それでも問題はありません。COM サーバーは VariantClear() を呼び出すだけでバリアントをリセットできます。それもやりたくないらしい。そのコードを修正することはできません。値を自分でリセットすることは、確かに十分な回避策です。

于 2012-11-14T18:03:16.247 に答える