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?
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.