Announcement

Collapse
No announcement yet.

LoadLibrary problem

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • LoadLibrary problem

    Hi,

    There's already many things on the forum about hooking DLLs but I can't find
    a solution to this one:

    Declare Sub RunThrough_Order Lib "test.DLL" Alias "RUNTHROUGH_ORDER" (ByRef TestString As String)

    Dim hLib As Long
    hLib = LoadLibrary(GetSystemDir & "\test.DLL")
    Call RunThrough_Order(teststring)
    Call FreeLibrary(hLib)

    (from a VB6 module)

    Calling the DLL (this code is a module) works just fine, but it is not released. At least,
    when I try to compile the DLL after calling it while my VB program is still open, PB Compiler
    provides a 'destination write file error'.

    What is it I do wrong? Do I HAVE to use GetProcAddress? Is it Win98? Or the PB Compiler?

    Hope someone can tell me.


    ------------------

  • #2
    You don't HAVE to use the loadlibrary, PB does this already for you.


    Also note, if it's a VB6 Module, is that the DLL or is it PB's DLL?

    If it's a VB6 DLL it's likely ActiveX and you won't be calling it from PB without the COM assistance..

    I don't have my code at work here, so I will post a sample later when I get home of what I used.

    Scott


    ------------------
    Scott
    mailto:[email protected][email protected]</A>
    Scott Turchin
    MCSE, MCP+I
    http://www.tngbbs.com
    ----------------------
    True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi

    Comment


    • #3
      Calling the DLL (this code is a module) works just fine, but it is not released. At least,
      when I try to compile the DLL after calling it while my VB program is still open, PB Compiler
      provides a 'destination write file error'.
      '----
      Cut and Paste from Eric Pearson post...
      The most common cause of a Destination File Write Error is that the DLL or EXE is "in use",
      i.e. the program is still running. Windows write-protects executable files while they are
      in use, so the compiler won't be able to overwrite the file until the program is closed.
      Sometimes, if a program GPFs or "End Task" is used, Windows (especially 95/98) will not
      unlock the file properly and you'll have to reboot.
      '----


      Regards, Jules
      Best regards
      Jules
      www.rpmarchildon.com

      Comment


      • #4
        You've got the DLL loaded twice-- once implicitly, when you directly call the declared sub, and once explicitly, when you use LoadLibrary. You're mixing two different calling techniques there. Drop one of them.

        ------------------
        Tom Hanlin
        PowerBASIC Staff

        Comment


        • #5
          Jeroen;

          Just using the Declare statement "forces" your PB DLL to get
          automatically loaded and "all" the functions in it get
          "automatically" referenced (find their address in memory) by your
          app.

          Now, when you use the LoadLibrary API function, this "does NOT happen".

          You must use the GetProcAddress API function to "find" the functions
          actual address and then use Call DWORD in PB (or its equivilant in
          other languages) to call the function.

          You also must always "explicitly" Free the Libary when done if you
          use Load Library, while it is not needed when the DLL is
          referenced using Declares (auto unloads as well).

          As Tom mentioned, there are "two" methods for using a DLL.


          ------------------
          Chris Boss
          Computer Workshop
          Developer of "EZGUI"
          http://cwsof.com
          http://twitter.com/EZGUIProGuy

          Comment


          • #6
            I'm sorry to bother you with a VB problem then, but I definitely would like to
            link the DLL explicitly.

            So in VB6 I do NOT declare the PB DLL (test.dll).
            I use:
            Dim hLib as Long
            hLib = LoadLibrary("test.dll")
            if hLib Then
            ptr = GetProcAddress(hLib), "RUNTHROUGH_ORDER")
            if ptr Then
            ????
            call Runthrough_Order(testString)
            end if
            end if
            Call FreeLibrary(hLib)

            What is the Call DWord equivalent in VB??
            If I don't declare the DLL, it doesn't understand the 'call runthrough_order', yet if I understand it right:
            if I declare the DLL it is 'locked' for the PB Compiler as long as my VB program is open, and that
            is exactly what I don't want.

            So what should go there?
            Hope you can help.



            ------------------

            Comment


            • #7
              IIRC, your VB declare should just omit the LIB "xxxx.DLL" portion.

              Post the declare you are using, and do not forget to test the returnvalue from FreeLibrary() to be sure that the DLL is being unloaded correctly... it may be working fine, but you could still be implicitly loading the DLL because of your declaration.




              ------------------
              Lance
              PowerBASIC Support
              mailto:[email protected][email protected]</A>
              Lance
              mailto:[email protected]

              Comment


              • #8
                Code:
                I think this worked, but still required a declare on the function.
                There is the other method to call using...
                
                                  hLib = LoadLibrary("SHORTCUT.DLL")
                                  If hLib Then
                                      procAddr = GetProcAddress(hLib, "CreateShortcut")
                                      Call @CreateShortCut(FilePath + WinLogEXE,"", sLocation, FilePath,2)
                                      Result = FreeLibrary(hLib)
                                  Else
                                      MsgBox "Unable to open DLL, file may be corrupt or missing",48, Mine
                                  End If
                ------------------
                Scott
                mailto:[email protected][email protected]</A>
                Scott Turchin
                MCSE, MCP+I
                http://www.tngbbs.com
                ----------------------
                True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi

                Comment


                • #9
                  Call pointer in VB ?! It's really something new for me.
                  Should I learn VB ?

                  PS. What I can't understand ...
                  In VB it's necessary simply declare
                  Declare Sub RunThrough_Order Lib "test.DLL" Alias "RUNTHROUGH_ORDER" (ByRef TestString As String)
                  and then it possible to use Call RunThrough_Order(teststring)
                  For what purpose LoadLibrary/FreeLibrary?


                  [This message has been edited by Semen Matusovski (edited July 15, 2000).]

                  Comment


                  • #10
                    I've a question too.

                    Can i get the current instance handle from an already (by PB) loaded DLL?
                    This way i can use CALL DWORD without referencing the DLL again.

                    ??

                    ------------------
                    [email protected]
                    hellobasic

                    Comment


                    • #11
                      Sorry Lance, but Semen is right: VB requires the Declare statement
                      including the Lib reference. Without it, VB produces an error.

                      >>For what purpose LoadLibrary/FreeLibrary?
                      Well, we've 'scripting' PB script using a VB interface and I want to compile
                      the code that's generated, and then test it (i.e. call the DLL).

                      If I declare the Sub, the DLL is hooked by the VB application and the PBDLL compiler generates
                      a 'destination write file error'.

                      So my question remains: how can I manually hook and unhook the PB DLL from VB when I call it,
                      therefore allowing the PBDLL compiler to (re)compile the generated code while my VB application is still running.

                      Hope someone knows.
                      Jeroen


                      ------------------


                      [This message has been edited by jeroen brouwers (edited July 15, 2000).]

                      Comment


                      • #12
                        Edwin --
                        >> Can i get the current instance handle from an already (by PB) loaded DLL?

                        Hope, that GetModuleHandle("xxx.Dll") should work.

                        Jeroen --
                        I can suggest only one way - to make a part of engine, which tests a PB-DLL, as separate Exe and to SHELL this Exe from main part of engine.


                        ------------------

                        Comment


                        • #13
                          ptr = GetProcAddress(hLib), "RUNTHROUGH_ORDER")
                          if ptr Then
                          ????
                          call Runthrough_Order(testString)
                          end if
                          A possible solution might be, creating a tiny wrapper DLL, just to call your function by something like:

                          Code:
                          ptr = GetProcAddress(hLib), "RUNTHROUGH_ORDER")
                          if ptr Then
                            call ptr
                          else
                            'problem
                          end if
                          Your VB app. can keep this DLL tied up while you dereference your main DLL from it after the call.
                          All you have to do for the final version is to change the "LIB wrapper.dll" part in the declare.


                          Peter.


                          ------------------
                          [email protected]

                          Comment


                          • #14
                            Peter's suggestion here is a good one, for very little overhead you can write
                            a small DLL that handles the calling of the address returned by GetProcAddress()
                            so that you just pass from VB, the returned address and the parameters in the
                            correct order.

                            I don't know if VB can use C calling convention but if it can, you can write a
                            general purpose DLL that remains loaded that you can use to do the call DWORD
                            style that PowerBASIC can do normally.

                            Regards,

                            [email protected]

                            ------------------
                            hutch at movsd dot com
                            The MASM Forum

                            www.masm32.com

                            Comment


                            • #15
                              Hmm ...
                              It looks that VB is more stupid (or clever) than I thought.
                              Tested under Win2000.
                              I used a full path for DLL, because I was too lazy to make special shortcuts.

                              PB:

                              Code:
                                 #Compile Dll "C:\H.Dll"
                                 Function Calc Alias "Calc" (i As Long) Export As Long
                                    Function = i * 3
                                 End Function
                              VB:
                              Code:
                              Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
                              Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
                              Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
                              Private Declare Function Calc Lib "C:\H.Dll" (i As Long) As Long
                              Private Sub Form_Load()
                                  MsgBox Calc(200)
                                  FreeLibrary GetModuleHandle("C:\H.Dll")
                                  MsgBox "Recompile"
                                  LoadLibrary "C:\H.Dll"
                                  MsgBox Calc(200)
                                  End
                              End Sub
                              Start a program. If to try to recompile after first Msgbox, you will receive "destination error".
                              When appears second Msgbox, change formula in PB and re-compile.
                              Third Msgbox gives new results.

                              ------------------

                              Comment


                              • #16
                                Thank you so much Semen,

                                This actually does work, I knew it could be done!
                                So the logic here seems this:

                                You declare a sub or function (in a PBDLL) in a VB app which links the DLL but does not hook it yet.
                                You declare a boolean (for instance Hooked) which is false (default).
                                You then call the sub or function which puts a hook on as part of the declare and explicitly free it,
                                so the hook from the declare is gone and the hook-unhook actions are even.
                                You put the Hooked to True and from that moment on you can hook and unhook it manually each time you call
                                the sub or function in the DLL.


                                Public Hooked As Boolean

                                If Hooked = True Then LoadLibrary ("C:\H.DLL")

                                Calc(200)
                                FreeLibray("C:\H.DLL
                                Hooked = true


                                Thank you so much.
                                Regards
                                Jeroen


                                ------------------

                                Comment


                                • #17
                                  Just an update from the use of this hooking and unhooking:
                                  USE IF ONLY IF YOU NEED IT!

                                  Vb doesn't seem to be very nice with the constant hooking and unhooking.

                                  The declare with a straight call to the sub or function works great, and stable too.



                                  ------------------

                                  Comment

                                  Working...
                                  X