Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Late binding run-time error in VB6 when creating an object from a .NET assembly

i have a vb6 project that has a reference to a vb.net com library.

the project runs well when i use early binding such as:

Dim b as object
Set b = new myComLib.testObject

when i use late binding such as:

Dim b as object
Set b = CreateObject("myComLib.testObject")

i get the following error:

Run-time error '429': ActiveX component can't create object

Any ideas?

thanks

like image 655
reven Avatar asked Feb 03 '12 07:02

reven


People also ask

What is late binding in VB net?

By contrast, an object is late bound when it is assigned to a variable declared to be of type Object . Objects of this type can hold references to any object, but lack many of the advantages of early-bound objects.

What is early binding and late binding in C# net?

Binding is an association of function calls to an object. The binding of a member function, which is called within an object and is called compiler time or static type or early binding. The binding of the function calls an object at the run time is called run time or dynamic or late binding.

What does late binding refers to?

NET, late binding refers to overriding a virtual method like C++ or implementing an interface. The compiler builds virtual tables for every virtual or interface method call which is used at run-time to determine the implementation to execute.


1 Answers

The registry entries for the .NET COM Interop class in this case are:-

HKEY_CLASSES_ROOT\myComLib.testObject 

containing a CLSID value and the CLSID entry itself

HKEY_CLASSES_ROOT\CLSID\<<myComLib.testObject\CLSID value>>

They are also replicated in

HKEY_LOCAL_MACHINE\SOFTWARE\Classes

CreateObject uses the HKEY_CLASSES_ROOT entries to retrieve the details of the class name passed in so if they're missing you will receive

Run-time error '429': ActiveX component can't create object

Within the VB6 IDE, adding a reference to the dll (in the case of a .NET assembly, via it's tlb file) bypasses this registry search thereby allowing the early binding to work without the COM registry entries.

The class has to be correctly registered for CreateObject to work. This should occur as part of the Visual Studio build process, otherwise it needs to be registered manually using Regasm.

You can test this behaviour by doing the following:-

1) Create a new VB.NET project myComLib registering for COM Interop in the project Compile properties and add a class testObject

Public Class testObject

    Public Property TestProperty As String

    Public Function TestFunction() As String
        Return "return"
    End Function

End Class

2) Build myComLib

3) Create a new VB6 project, add two command buttons to Form1 and the following code

Private Sub Command1_Click()
   Dim b As Object
   Set b = New myComLib.testObject
   b.TestProperty = "Hello"
   MsgBox b.TestProperty, vbOKOnly, b.TestFunction()
End Sub

Private Sub Command2_Click()
   Dim b As Object
   Set b = CreateObject("myComLib.testObject")
   b.TestProperty = "Hello"
   MsgBox b.TestProperty, vbOKOnly, b.TestFunction()
End Sub

4) Run the VB6 project (without full compile as that will fail)

Command2 will popup a message box, Command1 will fail with

Compile Error: User-defined type not defined.

5) Stop the project and add a reference to myComLib via it's tlb file

6) Run the VB6 project and both buttons should now work

7) Go into the registry and delete the HKEY_CLASSES_ROOT\myComLib.testObject entry (this can be re-created by Rebuilding the .NET component, you'll need to close VB6 to carry out the rebuild)

Command2 will now fail with

Run-time error '429': ActiveX component can't create object

until the registry entry is re-added.

like image 65
Michael Phillips Avatar answered Oct 04 '22 14:10

Michael Phillips