0

I'm calling a method in a for-loop that calls a method on a COM object (Inventor 2012).

The code used to be:

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

When refactoring I decided to inline the method call:

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

While changing nothing else, this started failing, throwing E_INVALIDARG. Furthermore, it only fails the second time the method is called. However, by changing it to the following it works again:

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

Why would this happen?

Edit:

Could it be that the COM-object reads the value of the previous iteration?

The signature is given in the documentation (in VB) as:

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

Is the C#-signature wrong? Aren't COM-interfaces auto-generated?

johv
  • 4,424
  • 3
  • 26
  • 42
  • Wouldn't the C# equivalent to the VB ByRef be the ref keyword rather than the out keyword? I'm not sure if that should make a difference but it might be worth a try? – Daniel Graham Nov 14 '12 at 16:55
  • `GetBaseQuantity(ref quantityType, ref quantity)` doesn't compile. – johv Nov 14 '12 at 16:59
  • Well, it just means the GetBaseQuantity is coded to reject the call when a non null quantity is passed. – Simon Mourier Nov 14 '12 at 17:00
  • As in the (presumably native?) code reads the value of the out-variable, rejecting non-null quantity? – johv Nov 14 '12 at 17:57

1 Answers1

0

Could it be that the COM-object reads the value of the previous iteration?

Yes it does. There's no equivalent of out in COM automation, other than for the return value of a method. How you ended up with out instead of ref is fairly mysterious. Probably just a bug in the IDL that was used to declare the COM interface. The only COM automation compatible IDL attributes are [in], [in,out] and [out,retval].

Still shouldn't be a problem, the COM server could just call VariantClear() to reset the variant. Seems it doesn't want to do that either. You can't fix that code, resetting the value yourself is certainly a good enough workaround.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536