When calling a function of an object in an out-of-process server and
passing a Variant array by reference, you get an access violation as below:
The instruction at '0x0f0fdbda' referenced memory at '0x0000b1a4'. The
memory could not be 'read'.
NOTE: The actual memory address may vary. This error occurs after you apply
the Service Pack 3 for Visual Basic 5.0
Refer to "Ways to Resolve the Problem" in the MORE INFORMATION section below.
Microsoft has confirmed this to be a bug in the Microsoft products listed
at the beginning of this article. This bug has been corrected in Microsoft
Visual Basic, version 6.0.
Steps to Reproduce Behavior
The following steps require MDAC 2.0 to be installed on the machine:
- Download and install MDAC 2.0.
You only need the minimum setup files.
- Alternatively, you can replace the existing oleaut32.dll with the
version shipped with MDAC 2.0 or Visual Basic 6.0 (2.30.4261).
Create the Server
- Create an ActiveX exe project and rename it ArraySvr.
- Add the following code to the default class module (Class1):
Public Function UseArray(ByRef vArray As Variant) As Boolean
UseArray = True
End Function
Public Function GetArray() As Variant
Dim vReturn As Variant
Dim vBstr As Variant
ReDim vReturn(1, 0) As Variant
vBstr = "Zero,Zero"
vReturn(0, 0) = vBstr
vBstr = "One,Zero"
vReturn(1, 0) = vBstr
GetArray = vReturn
End Function
- Compile the server.
Create and Test Client
- Create a Standard EXE project in Visual Basic. Form1 is created by
default.
- Add two CommandButtons and one Label to Form1.
- Select References from the Project menu and add a reference to ArraySvr.
- Add the following code to Form1:
Private vModule As Variant
Private Sub Command1_Click()
Dim o As ArraySvr.Class1
Set o = CreateObject("arraysvr.class1")
vModule = o.GetArray
Set o = Nothing
Command2.Enabled = True
End Sub
Private Sub Command2_Click()
Dim o As ArraySvr.Class1
Dim vLocal(1, 0) As Variant
Dim i As Long
Dim bRet As Boolean
For i = LBound(vModule, 1) To UBound(vModule, 1)
vLocal(i, 0) = vModule(i, 0)
Label1.Caption = vLocal(i, 0)
Set o = CreateObject("arraysvr.class1")
bRet = o.UseArray(vLocal)
Next i
Set o = Nothing
End Sub
Private Sub Form_Load()
Command2.Enabled = False
End Sub
- Press the F5 key to run the client.
- When you press Command1 and then Command2, you should see Label1
display "One,Zero."
- Compile the project into Native code.
- Run the compiled exe. When you press Command1 and then Command2, you
get a message as shown below:
The instruction at '0x0f0fdbda' referenced memory at '0x0000b1a4'.
The memory could not be 'read'.
Ways to Solve Problem
There are two ways to resolve this problem. You can either compile in P-
code or use a temporary Variant variable for the argument as shown in the
modified code below:
Private Sub Command2_Click()
Dim o As ArraySvr.Class1
Dim vLocal(1, 0) As Variant
Dim i As Long
Dim bRet As Boolean
Dim vTmp as Variant 'temporary variable for passing argument
For i = LBound(vModule, 1) To UBound(vModule, 1)
vLocal(i, 0) = vModule(i, 0)
Label1.Caption = vLocal(i, 0)
vTmp = vLocal
Set o = CreateObject("arraysvr.class1")
'instead of passing vLocal directly, we pass vTmp
bRet = o.UseArray(vTmp)
Next i
Set o = Nothing
End Sub