Author | Message | Time |
---|---|---|
Dyndrilliac | I'm writing a simple plugin engine in VB, but for some reason I keep getting Run-time Error '91', "Object variable or With block variable not set." I can't figure out why I'm getting the error. It's breaking on the error at the end of the f_LoadPlugins function. Here's my code for my TestApplication:[code]'// frmMain.frm Public Sub f_PrintText(sText As String) lblText.Caption = sText End Sub Private Sub cmdPluginActivate_Click() Dim i As Integer, PluginName As String For i = 0 To UBound(mdlPlugin.o_Plugins) If ((cboPlugins.Text) = (o_Plugins(i).p_Version)) Then Call o_Plugins(i).Main End If Next End Sub Private Sub Form_Load() Dim i As Integer Call mdlPlugin.f_LoadPlugins For i = 0 To UBound(o_Plugins) cboPlugins.AddItem o_Plugins(i).p_Version() Next i End Sub[/code][code]'// mdlPlugin.bas Option Explicit Public o_Plugins() As Object Public Sub f_LoadPlugins() 'On Error GoTo Error Dim s() As String, i As Integer, pId As String s() = f_GetFolderFiles(App.Path & "\Plugins", "*dll") If MsgBox("Have all your plugins been registered?", vbQuestion + vbYesNo, "Register") = vbNo Then For i = 0 To UBound(s) Shell "regsvr32 """ & s(i) & """", vbNormalFocus Next End If ReDim o_Plugins(0) For i = 0 To UBound(s) ReDim Preserve o_Plugins(i) pId = f_GetBaseName(s(i)) & ".Plugin" Debug.Print pId Debug.Print s(i) '// I'm using "Set" here. Set o_Plugins(i) = CreateObject(pId) o_Plugins(i).p_HostModule frmMain Next Exit Sub 'Error: 'MsgBox "A critical error has occurred!" & vbCrLf & " Error Number: " & Err.Number & vbCrLf & " Error Description: " & Err.Description & vbCrLf & " Source Plugin: " & mdlPlugin.o_Plugins(i).p_Version() & vbCrLf & "Please contact the plugin author for more information.", vbCritical + vbOKOnly, "f_LoadPlugins() Error!" End Sub Public Function f_GetFolderFiles(Folder As String, Optional Filter As String = ".*", Optional retFullPath As Boolean = True) As String() Dim FileNames() As String Dim Extension, FS As String If Not f_FolderExists(Folder) Then f_GetFolderFiles = FileNames() Exit Function End If Folder = IIf(Right$(Folder, 1) = "\", Folder, Folder & "\") If Left$(Filter, 1) = "*" Then Extension = Mid$(Filter, 2, Len(Filter)) If Left$(Filter, 1) <> "." Then Filter = "." & Filter FS = Dir$(Folder & "*" & Filter, vbHidden Or vbNormal Or vbReadOnly Or vbSystem) While FS <> vbNullString If FS <> vbNullString Then f_Push FileNames(), IIf(retFullPath = True, Folder & FS, FS) FS = Dir$() Wend f_GetFolderFiles = FileNames() End Function Public Function f_FolderExists(Path As String) As Boolean If Len(Path) = 0 Then Exit Function If Dir$(Path, vbDirectory) <> vbNullString Then f_FolderExists = True End Function Public Function f_GetBaseName(Path As String) As String Dim s() As String Dim ub As String s = Split(Path, "\") ub = s(UBound(s)) If InStr(1, ub, ".") > 0 Then f_GetBaseName = Mid$(ub, 1, InStrRev(ub, ".") - 1) Else f_GetBaseName = ub End If End Function Public Sub f_Push(sArray() As String, Value As Variant) On Error GoTo Error Dim i i = UBound(sArray) ReDim Preserve sArray(UBound(sArray) + 1) sArray(UBound(sArray)) = Value Exit Sub Error: ReDim sArray(0) sArray(0) = Value End Sub Public Function f_ArrayIsEmpty(sArray() As String) As Boolean On Error GoTo Error Dim i As Integer i = UBound(sArray) f_ArrayIsEmpty = False Exit Function Error: f_ArrayIsEmpty = True End Function[/code] And the TestPlugin's code:[code]'// clsPlugin.cls Option Explicit Private o_HostModule As Object Private s_PluginVersion As String Public Property Let p_HostModule(o_NewModule As Object) Set o_HostModule = o_NewModule End Property Public Property Get p_Version() As String p_Version = s_PluginVersion End Property Public Sub Main() MsgBox "Success! Everything is running fine!", vbExclamation + vbOKOnly, "Plugin is loaded!" o_HostModule.f_PrintText (p_Version() & " is running fine!") End Sub[/code] I have the ExamplePlugin.dll file in my "Plugins" subdirectory. | June 26, 2005, 10:47 AM |
Mangix | MSDN says [quote]You attempted to use an object property without a valid object. If you leave out the Set statement, an error will be generated on the reference to the object. To correct this error Specify a reference for the object variable.[/quote] btw: are you sure you can dim an array as an object? edit:on another note, you can make an object public however VB wont know what that object is. so you need to tell it what the object is :P. | June 26, 2005, 2:09 PM |
KkBlazekK | [quote author=Mangix link=topic=11980.msg117581#msg117581 date=1119794950] btw: are you sure you can dim an array as an object? [/quote]You can declare any type as an array. What line does it have problems with since I don't actually have to forms. | June 26, 2005, 4:20 PM |
Dyndrilliac | The program errors in this function at the bottom:[code]Public o_Plugins() As Object Public Sub f_LoadPlugins() 'On Error GoTo Error Dim s() As String, i As Integer, pId As String s() = f_GetFolderFiles(App.Path & "\Plugins", "*dll") If MsgBox("Have all your plugins been registered?", vbQuestion + vbYesNo, "Register") = vbNo Then For i = 0 To UBound(s) Shell "regsvr32 """ & s(i) & """", vbNormalFocus Next End If ReDim o_Plugins(0) For i = 0 To UBound(s) ReDim Preserve o_Plugins(i) pId = f_GetBaseName(s(i)) & ".Plugin" Debug.Print pId Debug.Print s(i) '// I'm using "Set" here. Set o_Plugins(i) = CreateObject(pId) o_Plugins(i).p_HostModule frmMain Next Exit Sub 'Error: 'MsgBox "A critical error has occurred!" & vbCrLf & " Error Number: " & Err.Number & vbCrLf & " Error Description: " & Err.Description & vbCrLf & " Source Plugin: " & mdlPlugin.o_Plugins(i).p_Version() & vbCrLf & "Please contact the plugin author for more information.", vbCritical + vbOKOnly, "f_LoadPlugins() Error!" End Sub[/code] Edit: Ok, I commented out the Error handler, and now it errors on the line where I'm using Set. It raises Run-time Error '429', "ActiveX Component can't create object." I looked this up on MSDN here. Apparently what this error really means is that the ProgId(pId) was not found or not supplied. More information revealed this: (MSDN) "You tried to place an ActiveX control on a form at design time or add a form to a project with an ActiveX control on it, but the associated information in the registry could not be found. " I don't get how this is happening, I made sure to perform a check allowing the users to register the .dll's in the registry. I added a couple debug statements before the Set command to give me the values of "pId" and "s(i)" (in that order). Here's my results:[quote]ExamplePlugin.Plugin C:\Documents and Settings\Matt\My Documents\Source Code\Visual Basic\Plugin Engine\Plugins\ExamplePlugin.dll[/quote] I can't figure out what's wrong :( >:( ??? :-[ :-\ :'( | June 26, 2005, 9:26 PM |
Mangix | instead of CreateObject, use "New pId". eg: [code]Set o_Plugins(i) As New pId[/code] | June 27, 2005, 4:56 AM |
Dyndrilliac | Why? CreateObject is far superior to VB's New keyword. It creates objects without a Type Library (that VB understands) and it creates objects that can recognize and comply with COM. | June 27, 2005, 6:24 AM |
Adron | It sounds like you need to look at why your plugin isn't registering correctly... | June 27, 2005, 12:56 PM |
Networks | I was really lazy to look through the source code...=\ but I am willing to give you my plugin loading procedure and hopefully it'll help you. [code] Public Sub Load_Plugins() Dim tmpPlugin As String ReDim Plugins(0) Dim i As Integer Dim strPath As String With frmMain .FPluginBox.Path = (App.Path & "\Plugins") .FPluginBox.Visible = False For i = 0 To .FPluginBox.ListCount - 1 strPath = App.Path & "\Plugins\" & .FPluginBox.List(i) Shell "regsvr32 " & Chr(34) & strPath & Chr(34) & " -s" Next i End With If frmMain.FPluginBox.ListCount > 0 Then frmMain.RTB2.SelText = vbNewLine End If 'Load Plugins For i = 0 To frmMain.FPluginBox.ListCount - 1 strPath = App.Path & "\Plugins\" & frmMain.FPluginBox.List(i) 'Debug.Print frmMain.FPluginBox.List(i) tmpPlugin = Split(frmMain.FPluginBox.List(i), ".dll")(0) Shell "regsvr32 " & Chr(34) & strPath & Chr(34) & " -s" Set Plugins(UBound(Plugins)).Plugin = CreateObject(tmpPlugin & ".clsMain") Plugins(UBound(Plugins)).Plugin_Name = tmpPlugin & ".dll" If Plugins(UBound(Plugins)).Plugin.SetHost(Me) = True Then ReDim Preserve Plugins(UBound(Plugins) + 1) AddC frmMain.RTB2, RGB(6, 110, 158), "Loaded Plugin: ", QBColor(7), frmMain.FPluginBox.List(i) Else AddC frmMain.RTB2, RGB(6, 110, 158), "Failed to load plugin: ", vbRed, frmMain.FPluginBox.List(i) End If Next i End Sub [/code] | June 28, 2005, 2:41 AM |
Dyndrilliac | Thanks. I think I see what's wrong now, I'm not passing the "-s" argument to the regsvr32 application via shell. That might be what's causing my plugins not to be registered properly. I'll check that avenue out as soon as I get home and post the results. Thanks for all your help guys. Edit: No go. Didn't help. Here's my updated code. Edit #2: Everything's fixed ;D ;) :) Thanks for all your guys' help. | June 28, 2005, 3:42 AM |
Networks | The '-s' just registers it silently opposed to the box popping up. | June 28, 2005, 3:50 PM |