Home All Groups Group Topic Archive Search About

vbAdvance general dll problem

Author
23 Aug 2010 11:41 AM
kbkforums via VBMonster.com
I want to create a plugin for an external application in VB6. To do this I
create a regular dll, export the necessary functions and compile the dll. So
far so good. The problem comes when I developed a second plugin (also in vb6
with vbAdvance) and try to load both in the external application. The first
plugin is loaded fine, but the second fails with error 998 (ERROR_NOACCESS).
I traced the problem to the code that starts the required vb stuff, in
MRuntimeInit:
...
pGetClass = GetProcAddress(hMod, "DllGetClassObject")
If pGetClass Then
   CopyMemory pCall, InitDelegator(FD, pGetClass), 4
   'Fails on next line
   lRet = pCall.Call(TA.iid, IID_ClassFactory, pICF)
...

Any ideas?

Thanks!

--
Message posted via http://www.vbmonster.com

Author
23 Aug 2010 12:31 PM
Schmidt
"kbkforums via VBMonster.com" <u63178@uwe> schrieb im Newsbeitrag
news:acf32440dbda5@uwe...

> I want to create a plugin for an external application in VB6.
Why not use VBs "native ActiveX-Dlls" for your
plugin-concept - why fiddle around with vbAdvance,
to expose the functionality as "normally Declarable StdCalls"
when you can have "real Objects instead" (meaning:
"work *with* VB, not against it" ... ;-)

Just define a Plugin-interface (basically emtpy Function-
Calls and Method-Defs) in a separate Dll-Project.
Compile that as MyInterface.dll - and the only Class
in it as eg.: iMyPlugin.

Then "tell" any Plugin-Writer, that his Plugin can
be implemented in a normal VB5/VB6 ActiveX-Dll,
by putting a reference to your "Interface Dll" in the
plugin-project - and using VBs Implements-Keyword.

In your Main-Project you would do the same, reference
the Interface-Dll - and load any external Plugin-Library
against this Interface.

'In your Main-Project..

Dim SomePlugin As iMyPlugin 'declare the Plugin-Type

'load and cast the MainClass in your Plugin against the
'predefined iMyPlugin-Variable
Set SomePlugin = CreateInstanceRegfree( _
                            PluginDllFileName, "MainClass")


The above mentioned MyInterface.dll would not need
to be deployed at all - it is only there, to provide the
Plugin-Interface into your Main-Project - as well as
into the Plugin-Writers Dll-Projects.

And regarding RegFree instantiations directly per "Plugin-
Filename" - there are helper-solutions available.
(e.g. per 20kByte DirectCOM.dll - which you would need
to place beside your Main.exe)

Olaf
Author
23 Aug 2010 12:42 PM
kbkforums via VBMonster.com
The external application requires that plugins expose their functionality as
"stdcalls"

Schmidt wrote:
Show quoteHide quote
>> I want to create a plugin for an external application in VB6.
>Why not use VBs "native ActiveX-Dlls" for your
>plugin-concept - why fiddle around with vbAdvance,
>to expose the functionality as "normally Declarable StdCalls"
>when you can have "real Objects instead" (meaning:
>"work *with* VB, not against it" ... ;-)
>
>Just define a Plugin-interface (basically emtpy Function-
>Calls and Method-Defs) in a separate Dll-Project.
>Compile that as MyInterface.dll - and the only Class
>in it as eg.: iMyPlugin.
>
>Then "tell" any Plugin-Writer, that his Plugin can
>be implemented in a normal VB5/VB6 ActiveX-Dll,
>by putting a reference to your "Interface Dll" in the
>plugin-project - and using VBs Implements-Keyword.
>
>In your Main-Project you would do the same, reference
>the Interface-Dll - and load any external Plugin-Library
>against this Interface.
>
>'In your Main-Project..
>
>Dim SomePlugin As iMyPlugin 'declare the Plugin-Type
>
>'load and cast the MainClass in your Plugin against the
>'predefined iMyPlugin-Variable
>Set SomePlugin = CreateInstanceRegfree( _
>                            PluginDllFileName, "MainClass")
>
>The above mentioned MyInterface.dll would not need
>to be deployed at all - it is only there, to provide the
>Plugin-Interface into your Main-Project - as well as
>into the Plugin-Writers Dll-Projects.
>
>And regarding RegFree instantiations directly per "Plugin-
>Filename" - there are helper-solutions available.
>(e.g. per 20kByte DirectCOM.dll - which you would need
>to place beside your Main.exe)
>
>Olaf

--
Message posted via VBMonster.com
http://www.vbmonster.com/Uwe/Forums.aspx/vb/201008/1
Author
23 Aug 2010 1:24 PM
Schmidt
"kbkforums via VBMonster.com" <u63178@uwe> schrieb im Newsbeitrag
news:acf3ae2ebc0a7@uwe...

> The external application requires that plugins expose
> their functionality as "stdcalls"
So you are apparently a Plugin-Writer then...

Ok, in case this "external application" was not written
yourself (in VB5/6) - then why not use another, more
suitable language, to produce your StdCall-plugin-dll(s)?

E.g. FreeBasic is one such language, which allows to
produce Windows-StdCall-Dlls in Basic-Syntax.
FreeBasic is in this regard very similar to PowerBasic,
but usable for free - coming under LGPL.

Please look at www.freebasic.net for more information.

Olaf
Author
23 Aug 2010 2:35 PM
Kevin Provance
"kbkforums via VBMonster.com" <u63178@uwe> wrote in message
news:acf32440dbda5@uwe...
Show quoteHide quote
:I want to create a plugin for an external application in VB6. To do this I
: create a regular dll, export the necessary functions and compile the dll.
So
: far so good. The problem comes when I developed a second plugin (also in
vb6
: with vbAdvance) and try to load both in the external application. The
first
: plugin is loaded fine, but the second fails with error 998
(ERROR_NOACCESS).
: I traced the problem to the code that starts the required vb stuff, in
: MRuntimeInit:
: ..
: pGetClass = GetProcAddress(hMod, "DllGetClassObject")
: If pGetClass Then
:   CopyMemory pCall, InitDelegator(FD, pGetClass), 4
:   'Fails on next line
:   lRet = pCall.Call(TA.iid, IID_ClassFactory, pICF)
: ..

This code is incomplete.  What file is used to get the return value of hMod?
Author
24 Aug 2010 7:44 AM
kbkforums via VBMonster.com
Complete code:

Public Function DllMain(ByVal hinstDLL As Long, ByVal fdwReason As Long,
ByVal lpvReserved As Long) As Long

    Const DLL_PROCESS_ATTACH As Long = 1
    Const DLL_PROCESS_DETACH As Long = 0

    If fdwReason = DLL_PROCESS_ATTACH Then

        'Initialize the VB Runtime when this DLL is first
        'loaded by a process:
         RuntimeInitialize hinstDLL

        'Must return TRUE for success:
        DllMain = 1

    ElseIf fdwReason = DLL_PROCESS_DETACH Then

        DllMain = 1

    End If

End Function

In module MRuntimeInit (from vbAdvance samples):

Public Sub RuntimeInitialize(ByVal hMod As Long)

    Dim sFile As String
    Dim lLen As Long
    Dim lRet As Long
    Dim i As Long
    Dim lpTypeLib As Long
    Dim TLI As ITypeLib
    Dim lppTypeInfo As Long
    Dim TI As ITypeInfo
    Dim sName As String
    Dim pAttr As Long
    Dim TA As TYPEATTR
    Dim IID_ClassFactory As VBGUID
    Dim IID_IUnknown As VBGUID
    Dim pGetClass As Long
    Dim pCall As ICallDLLGetClassObject
    Dim FD As FunctionDelegator
    Dim pICF As IClassFactory
    Dim pUnk As IUnknown

    'Make sure parent process is not VB IDE:
    If GetModuleHandle("VBA6.DLL") <> 0 Then Exit Sub
    If GetModuleHandle("VBA5.DLL") <> 0 Then Exit Sub

    sFile = Space$(260)
    lLen = Len(sFile)
    lRet = GetModuleFileName(hMod, sFile, lLen)
    If lRet Then
        sFile = Left$(sFile, lLen - 1)
        lpTypeLib = LoadTypeLibEx(sFile, REGKIND_NONE)
        CopyMemory TLI, lpTypeLib, 4
        For i = 0 To TLI.GetTypeInfoCount - 1
            If TLI.GetTypeInfoType(i) = TKIND_COCLASS Then
                lppTypeInfo = TLI.GetTypeInfo(i)
                CopyMemory TI, lppTypeInfo, 4
                TI.GetDocumentation DISPID_UNKNOWN, sName, "", 0, ""
                If lstrcmp(sName, "CRuntimeInit") = 0 Then
                    pAttr = TI.GetTypeAttr
                    CopyMemory TA, ByVal pAttr, Len(TA)
                    TI.ReleaseTypeAttr pAttr
                    If TA.wTypeFlags Then
                        Exit For
                    End If
                End If
            End If
        Next i
        With IID_ClassFactory
            .Data1 = 1
            .Data4(0) = &HC0
            .Data4(7) = &H46
        End With
        With IID_IUnknown
            .Data4(0) = &HC0
            .Data4(7) = &H46
        End With
        pGetClass = GetProcAddress(hMod, "DllGetClassObject")
        If pGetClass Then
            CopyMemory pCall, InitDelegator(FD, pGetClass), 4
            lRet = pCall.Call(TA.iid, IID_ClassFactory, pICF)
'Fails on this line!!!!!
            If lRet <> CLASS_E_CLASSNOTAVAILABLE Then
                lRet = pICF.CreateInstance(0&, IID_IUnknown, pUnk)
                If lRet = S_OK Then
                    Set moInitObject = pUnk
                    moInitObject.InitVBCall
                    CopyMemory pCall, 0&, 4
                    Set pICF = Nothing
                    Set pUnk = Nothing
                End If
            End If
        End If
    End If
End Sub

Kevin Provance wrote:
>:I want to create a plugin for an external application in VB6. To do this I
>: create a regular dll, export the necessary functions and compile the dll. So
>[quoted text clipped - 10 lines]
>:   lRet = pCall.Call(TA.iid, IID_ClassFactory, pICF)
>: ..
>
>This code is incomplete.  What file is used to get the return value of hMod?

--
Message posted via http://www.vbmonster.com