4

I have a legacy VB6 application that calls a VB6 DLL, and I am trying to port the VB6 DLL to C# without yet touching the main VB6 application code. The old VB6 DLL had one interface that received a VB6 long (32-bit integer) by reference, and updated the value. In the C# DLL I have written, the updated value is never seen by the main VB6 application. It acts as though what was really marshalled to the C# DLL was a reference to a copy of the original data, not a reference to the original data. I can successfully pass arrays by reference, and update them, but single values aren't behaving.

The C# DLL code looks something like this:

[ComVisible(true)]
public interface IInteropDLL
{
   void Increment(ref Int32 num);
}
[ComVisible(true)]
public class InteropDLL : IInteropDLL
{
    public void Increment(ref Int32 num) { num++; }
}

The calling VB6 code looks something like this:

Private dll As IInteropDLL
Private Sub Form_Load()
    Set dll = New InteropDLL
End Sub
Private Sub TestLongReference()
    Dim num As Long
    num = 1
    dll.Increment( num )
    Debug.Print num      ' prints 1, not 2.  Why?
End Sub

What am I doing wrong? What would I have to do to fix it? Thanks in advance.

edj
  • 523
  • 7
  • 17
  • As C# allows you direct control over the classIDs, you can completeley emulate the odl COM interface so no changes required in the client either. – Deanna Nov 10 '11 at 09:52
  • Does this answer your question? [VB6 pass by value and pass by reference](https://stackoverflow.com/questions/10262186/vb6-pass-by-value-and-pass-by-reference) – chris neilsen Sep 26 '21 at 19:51

1 Answers1

10
dll.Increment( num )

Because you are using parentheses, the value is forcibly passed by value, not by reference (the compiler creates a temporary copy and passes that by reference).

Remove the parentheses:

dll.Increment num

EDIT: A more complete explanation by MarkJ.

Community
  • 1
  • 1
GSerg
  • 76,472
  • 17
  • 159
  • 346
  • 1
    Nice call. Definitely one of the more bizarro features of VB6. It makes sense that it works that way but it takes some imagination. Argument passing was ByRef by default. – Hans Passant Nov 09 '11 at 19:10
  • That was it! Wow! I never knew about that behavior of VB6. Now that I know this, I can think of other times I was bitten, but just found other workarounds. Thanks!! – edj Nov 09 '11 at 21:14
  • Oh, and please copy and paste code sample, not rewrite/obfuscate as it can hide oddities/bugs like that. – Deanna Nov 10 '11 at 09:52
  • The paranthesis behavior in this case changes in you had useed Call instead. I *always* use the Call MyMethed(Param) convention to avoid that evaluation behavior. Plus The C and Java in my past makes me uneasy if I don't see paranthesis when invoking functions :) – tcarvin Nov 10 '11 at 12:52
  • 1
    If you see a space between your method call and the first bracket `MethodCall ("foo")`- this is your queue to investigate an issue - either remove the brackets or add `Call`. After some time, spotting this becomes second nature! – Matt Wilko Nov 14 '11 at 13:39