VB6, ByRef, ByVal and Interop

While COM Interop may have some drawbacks, many times it is a necessary step (budget constraints, time constraints, etc...). If you're currently developing VB6 objects that may some day be used in .NET via interop then now is the time to get your ByRef's and ByVal's cleared up. It will make your interop experience much more enjoyable.

As you probably know, passing an object "by reference" (ByRef) means the method that receives the argument can change the value of the argument. On the other hand, passing it "by value" (ByVal) means a copy of the argument is made and the method only receives a copy. There is no way to update the caller's argument that was passed in. VB6 has a default of "ByRef". However, unless you explicitly need to update one of your method arguments, you really should be passing everything ByVal.

Here's an example of where this can turn into a headache for you if you ever do COM Interop. He's a fictional VB6 "Clothes" object:

   Option Explicit

   Public Enum ShirtSize
      Small = 1
      Medium = 2
      Larger = 3
   End Enum

Public Sub BuyShirt(size As ShirtSize)
End Sub

You may have some VB6 code that consumes this method using:

   Dim myShirt As Shirt
    
   Set myShirt = New Shirt
   Call myShirt.BuyShirt(Medium)

And everything works just fine.

Now you create a wrapper for this COM object because you need to consume it from your brand new .NET application. Since VB6 defaults to ByRef arguments, the "size" argument in BuyShirt is a reference object. You may want to write some .NET code like this:

   Shirt myShirt = new ShirtClass();
   myShirt.BuyShirt(ShirtSize.Medium);

But that won't compile. You can't pass ShirtSize.Medium because .NET wants a ref parameter (just like the signature in COM). Therefore, to get this to work, you need an ugly workaround:

   Shirt myShirt = new ShirtClass();
   ShirtSize medium = ShirtSize.Medium;
   myShirt.BuyShirt(ref medium);

Consider yourself warned. Be wary of the VB6 code you're developing today and plan for the future.

No Comments