Microsoft KB Archive/189156

= BUG: Crash When Closing Application That Uses ActiveX DLL =

Article ID: 189156

Article Last Modified on 5/13/2003

-

APPLIES TO


 * Microsoft Visual Basic 5.0 Learning Edition
 * Microsoft Visual Basic 6.0 Learning Edition
 * Microsoft Visual Basic 5.0 Professional Edition
 * Microsoft Visual Basic 6.0 Professional Edition
 * Microsoft Visual Basic 5.0 Enterprise Edition
 * Microsoft Visual Basic 6.0 Enterprise Edition

-



This article was previously published under Q189156



SYMPTOMS
Using Visual Basic, you create one or more ActiveX DLLs and a Standard EXE (client) application to use the DLLs. The client application runs as expected within the Visual Basic (IDE) environment. However, when you compile and run the client application as an EXE, the application produces one of the following errors upon closing:

caused an invalid page fault in module MSVBVM50.DLL at 0137:0f059b41.

-or-

Exception: access violation (0xc0000005), Address: 0x0f059b41



CAUSE
This problem can occur when the objects you create in the DLL are not closed properly by the client application due to a circular reference. A circular reference occurs, for instance, in the following scenario:

A client application instantiates an object in the ActiveX DLL: the Parent object. The Parent object creates another object in the DLL: the Child object. The Parent object sets a property in the Child object that allows the Child object to have a reference to the Parent object.

This creates a circular reference between the Parent and Child objects. When the client application that created the Parent object sets its object variable to Nothing, the Parent object does not terminate because the Child object maintains a reference to the Parent object. The MORE INFORMATION section below describes a specific case for this problem and provides a solution, which is to remove the Child's reference to the Parent object before closing the Parent object.



STATUS
Microsoft is researching this problem and will post new information here in the Microsoft Knowledge Base as it becomes available.



MORE INFORMATION
The steps below illustrate two sample ActiveX DLLs and a client application to use the DLLs. By following these steps, you will see how an error can occur when you close the client application. A workaround is also provided.

Steps to Reproduce Behavior
 Start Visual Basic and create a new ActiveX DLL project. Class1 is created by default. Change the name of the Class1 module to GlobalMethods. Choose Properties from the Project menu, and set the Project Name to UBGlobal.  Put the following code in the GlobalMethods module: Option Explicit

Public Sub gMethod1

End Sub

Public Function getValidList(a As Object, b As Collection) As Integer End Function

 Save the UBGlobal project and make UBGlobal.dll. Close the UBGlobal project and start a new ActiveX DLL project. Class1 is created by default.</li> Choose References from the Project menu, and set a reference to UBGlobal.</li> Choose Properties from the Project menu, and set the Project Name to UBServer.</li> From the Project menu, add a new class module. Class2 is created.</li>  Put the following code in the Class2 module: Option Explicit

Public objGlobal As UBGlobal.GlobalMethods Public objParent As Class1

Private Sub Class_Initialize Set objGlobal = New UBGlobal.GlobalMethods objGlobal.gMethod1 End Sub

Private Sub Class_Terminate Set objGlobal = Nothing End Sub

</li>  Put the following code in the Class1 module: Option Explicit

Private objChild As Class2

Private Sub Class_Initialize Set objChild = New Class2 Set objChild.objParent = Me     End Sub

Private Sub Class_Terminate Set objChild.objParent = Nothing Set objChild = Nothing End Sub

Public Sub CleanUp Set objChild.objParent = Nothing End Sub </li> Save the UBServer project and make UBServer.dll.</li> Close the UBServer project, and start a new Standard EXE project. Form1 is created by default.</li> Choose References from the Project menu, and set a reference to both UBGlobal and UBServer.</li> Choose Properties from the Project menu, and set the Project Name to Client.</li> Put a CommandButton on Form1.</li>  Put the following code in the form's code window: Option Explicit

Dim objGlobal As UBGlobal.GlobalMethods Dim objParent As UBServer.Class1

Private Sub Form_Load Set objGlobal = New UBGlobal.GlobalMethods objGlobal.gMethod1 Set objParent = New UBServer.Class1 End Sub

Private Sub Command1_Click ' uncomment the following line for solution: 'objParent.CleanUp Set objParent = Nothing Set objGlobal = Nothing Unload Me     End Sub </li> Run the project. The form with the CommandButton appears.</li> Click the CommandButton. Note that the application ends without an error.</li> Save the Client project and compile Client.exe.</li> Close Visual Basic.</li> <li>Run Client.exe. The form with the CommandButton appears.</li> <li>Click the CommandButton.</li></ol>

Result: The client application terminates with one of the errors described above.

Solution: Uncomment the objParent.CleanUp line in the client project. Recompile and run Client exe. Click the CommandButton.

Result: The application shuts down properly with no error.

The purpose of the CleanUp method in Class1 is to remove the circular reference between Class1 (parent) and Class2 (child). Until the reference to Class1 is removed, Class1 does not terminate properly when using the ActiveX DLL from a Visual Basic client EXE.

<div class="references_section">