Bug (?) in AxImp in .NET Framework 1.1 SP1
Here's one of those fun issues that may or may not be a bug, depending on how you look at it.
With our product we provide an ActiveX control, written in VB6. Increasingly, customers having been writing rich client apps using .NET rather than VB6, and our ActiveX control has worked just fine in that environment. Until .NET 1.1 SP1 (and .NET 1.0 SP2), that is.
After installing 1.1 SP1, attempting to add the ActiveX control to a Windows Forms form in Visual Studio displayed the rather cryptic error "Invalid Primitive Type: System.Reflection.Missing. Only CLS compliant primitive types can be used. Consider using CodeObjectCreateExpression.". Huh?
Using the AxImp tool with the /source parameter provided a little more insight (although with an even more cryptic error - "The file can not be opened because it's in use by another process" - resulting in a truncated, incomplete .CS file). It turns out that some of the methods on our control contained non-variant optional arguments that don't define default values. For example, a method that results in this IDL:
HRESULT FunctionWithOptionalsNoVals([in, optional] double dVal, [out, retval] BSTR* );
would work in 1.1, but not 1.1 SP1.
A quick search of the MSKB revealed this article - apparently the original framework didn't properly support default values in ActiveX controls so they changed it. That change caused the framework to choke on our control.
So is this a bug? It turns out that's not a simple question to answer. In the sense that it broke previously functional code, yes it's a bug. But it raises a different question - was our method definition valid to begin with?
Unfortunately, the answer to that question seems to be indeterminate. Why? Because the OLE Automation spec describes the optional attribute as "valid only if the parameter is of type VARIANT or VARIANT*". But clearly that isn't true - VB6 (and most every other programming language) will happily let you create a non-variant optional argument, and its quite common to see that in type libraries. Nor is the defaultvalue attribute required by the compiler when the optional attribute is specified (and clearly VB6 will happily allow you to specify optional without defaultvalue, although the semantics of that is unclear).
Bug? If so, where? The COM spec? VB6? AxImp? No matter how you slice it, it's yucky. Fortunately, the fix is relatively simple - specify a default value, which we should have done originally anyway.