Announcement

Collapse
No announcement yet.

Declaring optional DLL files

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

  • Declaring optional DLL files

    I have a program that may or may not use a piece of hardware that requires a DLL provided by the manufacturer.

    If the user selects not to use/not use the hardware, how should I go about declaring/not declaring functions in the DLL?

    Normally I see these declared near the top of the program, but the program will give a runtime error if it can't find the DLL.

    It would be nice to not need to have the DLL around if the hardware is not being used.
    Gary Peek, Industrologic, Inc.

  • #2
    Gary, I asked PowerBASIC support that question and here's what they sent back. I haven't followed up on using the information, so I don't have an example to give.

    PowerBASIC Support:
    Sure, you would use LoadLibrary to load the DLL, then GetProcAddress to get the address of the procedure, then use CALL DWORD to call this address. You will also create a modified declare statement that does not specify the libraries name. This is explained in the CALL DWORD statement in the help file.

    Gary Beene wrote:
    I would like to use an external DLL in one of my apps, but have distribution of it be optional.

    In my tests, compiling with a DLL but not including it with the EXE causes an error when the EXE tries to run.

    Is there a way to create/compile my application to run without the DLL when the DLL is not present (with the DLL features missing, of course)?

    I have only 1 subroutine that needs the DLL – 99.9% of the app doesn’t use it.

    Comment


    • #3
      Actually, your question prompted me to give it a try. Here's a compilable example that seems to work just fine.

      In this case,the WinMsg.DLL that comes with PowerBASIC examples is declared (see the modified declared statement). Then, when you press the button the LoadLibrary is used to get a pointer to the address of the procedure of interest, which is then executed using CALL DWORD. It seems to work pretty smoothly.

      Code:
      'Compilable Example:
      #Compile Exe
      #Dim All
      #Include "Win32API.inc"
      'Declare Function WinMsg LIB "WINMSG.DLL" ALIAS "WindowMessageA" (BYVAL MsgNum AS LONG) AS String
      Declare Function WinMsg (ByVal MsgNum As Long) As String   'take out LIB and ALIAS sections
      Global hDlg As Dword
      Function PBMain() As Long
         Dialog New Pixels, 0, "Test Code",300,300,200,200, %WS_OverlappedWindow To hDlg
         Control Add Button, hDlg, 100,"Push", 50,10,100,20
         Dialog Show Modal hDlg Call DlgProc
      End Function
      CallBack Function DlgProc() As Long
         If Cb.Msg = %WM_Command And Cb.Ctl = 100 And Cb.CtlMsg = %BN_Clicked Then
            Dim hLib As Dword, pAddress As Dword, Result As String
            hLib = LoadLibrary("winmsg.dll")
            pAddress = GetProcAddress(hLib, "WindowMessageA")    'use ALIAS
            Call Dword pAddress Using WinMsg(%WM_InitDialog) To Result  'use Declared name
            FreeLibrary hLib
            MsgBox Result
         End If
      End Function
      Thanks for asking the question, else I wouldn't have remembered to follow up on the support suggestion. I'll add this to the gbSnippets PowerBASIC source code library.
      Last edited by Gary Beene; 18 Nov 2009, 10:11 PM.

      Comment


      • #4
        Thank You!

        Well, thank you very much Gary, for providing that example.
        Gary Peek, Industrologic, Inc.

        Comment


        • #5
          If a function is declared as external ("LIB xxxx.dll") and is called anywhere in the module code, that library file will be added to the module's import table, and will be required to load the module; regardless if that module is loaded to start a new process (an EXE file) or is requested at load time by another module (a DLL file). If absent Windows will fail the application with "one or more components of 'program' cannot be found" (message varies with Windows' version).

          If it's not declared as external, it is not requred at runtime.

          It really is that straightforward.
          Michael Mattias
          Tal Systems (retired)
          Port Washington WI USA
          [email protected]
          http://www.talsystems.com

          Comment


          • #6
            Hi Michael,

            I'm not quite sure of the point you were trying to get me to understand. I think you were confirming the example I gave, but I'm not quite sure.

            By not putting in a "LIB xxx.dll", I declared the function as internal, not external.

            In the example I gave, I could have added "IsFile" code to determine if the DLL were available and run the LoadLibrary code only if the DLL file was found. That's really the question Gary was asking - how to be able to load a DLL on demand. It does require the declaration of a function, with arguments matching that of the external dll function - but declared as an internal, not external, function.

            Did I miss your point?

            Gary, here's the LoadLibrary portion of the code, with IsFile used to load the external library only if the DLL exists.

            Code:
                  If IsFile("winmsg.dll") Then
                     hLib = LoadLibrary("winmsg.dll")
                     pAddress = GetProcAddress(hLib, "WindowMessageA")    'use ALIAS
                     Call DWord pAddress Using WinMsg(%WM_InitDialog) To Result  'use Declared name
                     FreeLibrary hLib
                     MsgBox Result
                  End If

            Comment


            • #7
              >Did I miss your point?

              Probably, but that's because I took the long way and tried to cover all the possibilities.

              Bottom line is, If you use a function DECLAREd as External, the "LIB" file in that DECLARE statement must be present at runtime or the program will not run.

              E.g, both The Provider Payment Partner(tm) System and the EDI Pal(tm) ANSI X12 Viewer-Editor-Printer are offered with priced add-on features; these features are supplied as DLL files. Since not everyone licenses ALL the features, the main programs do not declare any of these "feature functions" as external, as the users expect the programs to run even when they don't purchase all the additional bells and whistles.


              MCM
              Michael Mattias
              Tal Systems (retired)
              Port Washington WI USA
              [email protected]
              http://www.talsystems.com

              Comment


              • #8
                MCM,

                The way you say if a function is "declared as external" that LIB "must be present" is caught my attention.

                Without LIB in the DECLARE, is there another way to declare a function as external? I thought LIB was the mechanism for declaring a function as external.

                The way you wrote your post suggests there is another way to declare a function as external. Is there? I couldn't find it in Help so I thought I'd ask to see if I missed something.

                I think we're in sync, but it wouldn't be the first time that I wandered afar from what a Help topic was telling me.

                Comment


                • #9
                  Please be sure to add error checking if this is going into a production program. You really do not want to call the function if the LoadLibrary fails, or the GetProcAddress.

                  Comment


                  • #10
                    DECLARE is a compiler directive; it names the symbols which are procedures.

                    When the optional "LIB xxxx" clause apprears in the DECLARE statement, that's what tells the compiler it's an external procedure; and if that function is used in the module, that library file is added to the import table of the compiled module.

                    The side effect is, once the library file appears in the import table, the module can only be loaded if that library file is available at runtime.

                    Show exports and imports for PB/Win 6x, 7x (original by Torsten Reinow)
                    Michael Mattias
                    Tal Systems (retired)
                    Port Washington WI USA
                    [email protected]
                    http://www.talsystems.com

                    Comment


                    • #11
                      Gary, you and Michael are in sync, you just had the terminology wrong. Any time you access code in a DLL that code is considered external to your executable code. When you use DECLARE with the LIB option, you are telling the compiler that the procedure being declared is contained in the external code of the DLL specified. If you use declare without the LIB option you are telling the compiler the form that a call to that procedure will take (name, number and types of parameters and return type) whether it is internal (included in your source code and used by explicit or implicit CALL statements) or external (used with CALL DWORD after loading the library and getting the procedures address).
                      Jeff Blakeney

                      Comment

                      Working...
                      X