Announcement

Collapse
No announcement yet.

Passing variables between EXE and DLL

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

  • Passing variables between EXE and DLL

    Hello gurus,

    I have an executable with lots of global UDT's and I would like
    to share those with the DLL's I've made. An update of the
    global UDT's in the DLL should be reflected also in the EXE and
    vice-versa

    How can I approach this ? I can't find any reference regarding
    this issue in the FAQ. Do I have to resort to memory mapped
    files ??

    Thanks !
    Steve

    ------------------
    So here we are, this is the end.
    But all that dies, is born again.
    - From The Ashes (In This Moment)

  • #2
    Send the varptr(x) along
    Use dim x as type ptr

    or even better, include the type as one of your function parameters.
    This is allways byref..


    ------------------
    hellobasic

    Comment


    • #3
      Hi Edwin,

      Actually, I have a bunch of UDT's and I want to use them all
      in the DLL. Do I have to pass them over one by one ?? Isn't
      there a faster way to just map all the globals from my EXE
      into my DLL ? It would be like a two-way communication. An
      update of the UDT in the DLL is reflected in the EXE as well.

      So, your approach is OK but then I have to call twenty times
      the function to pass back and forth my variables.

      Hope this makes sense...

      ------------------
      So here we are, this is the end.
      But all that dies, is born again.
      - From The Ashes (In This Moment)

      Comment


      • #4
        I guess you have a problem there.
        You can not make them 'global' but you can fully exchange them using pointers
        A byref parameter exchange is in fact also a pointer.
        The thing you could do is using some initialize procedure setting global vars as PTR in your dll
        They should point to the type's address in your exe.
        This way you are able to reach the data in both 'apps'
        You could prepare an array of type structures and send them along to the dll..




        ------------------
        hellobasic

        Comment


        • #5
          Steven, firstly, you probably have a good reason but I have to ask - Why do you have a DLL which you wrote being used from a program you also wrote? Are the executable and the dll written in PBDLL/PBCC? It seems the simple solution is to place the DLL code into your PB app (if the DLL was written with PBDLL).

          Have you looked into using SendMessage with WM_COPYDATA?

          [This message has been edited by Ron Pierce (edited June 06, 2001).]

          Comment


          • #6
            If you really want to share these UDTs, Store the data in a memory-mapped file which both your EXE and DLL can access.

            Or...

            what I have done in the past (DOS days, I program better than this now), is to include a FUNCTION in each module which has as ts sole purpose returning the current value of selected datanames.

            Code:
            GLOBAL foo, bar, baz
            FUNCTION getCurrentDataValues (A, B, C) EXPORT AS LONG 
             A = foo: b=bar:c=baz
            END FUNCTION
            Call the above from the "other" module.

            MCM

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

            Comment


            • #7
              Hi Ron,

              Well, the reason is that I would like to build an application
              that can be update similarely like norton antivirus gets it's
              updates. Also, I like to keep my code regarding dialogs in a
              DLL since this would make it easier to deal with multi-lingual
              issues. And... last but not least... there seems to be some
              problems with compiling large source-files !! Both my exe and
              DLL's are created using PB/DLL and unfortunately PB/DLL doesn't
              export variables like Visual C++ does.

              The pointer stuff that Edwin adviced me works OK though
              another way is to use a file and put the vars inthere and load
              the file when necessary (dirty but works quite well )



              ------------------
              So here we are, this is the end.
              But all that dies, is born again.
              - From The Ashes (In This Moment)

              Comment


              • #8
                How about creating a DWORD array, and placing the VARPTR of the individual UDT's into the array, then pass the whole array to the DLL (which is a BYREF pass). This way you only pass one 32-bit parameter to the DLL, so that part is efficient.

                This means you only need to deal with UDT Pointers in the DLL.

                For example (in pseudocode):
                Code:
                ' The main code
                DECLARE SUB MyDLL LIB "MYDLL.DLL" (UDTArray() AS DWORD)
                ...
                DIM UDTArray(0:3) AS DWORD ' probably want a static or global array in the main code
                UDTArray(0) = VARPTR(UDT1)
                UDTArray(1) = VARPTR(UDT2)
                UDTArray(2) = VARPTR(UDT3)
                UDTArray(3) = VARPTR(UDT4)
                CALL MyDLL(UDTArray())
                 
                ' The DLL code
                SUB MyDLL(UDTARRAY() AS DWORD) EXPORT
                  DIM UDT1 AS UDT1TYPE PTR
                  UDT1 = UDTARRAY(0)
                  @UDT1.member = "dadada"
                  DIM UDT2 AS UDT1TYPE PTR
                  UDT2 = UDTARRAY(1)
                  .. etc
                The strategy is vastly more efficient than using a disk file, and effectively makes the UDT's "global" between the EXE and the DLL.


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

                Comment


                • #9
                  Steve,

                  I would be inclined to use a LARGE structure (UDT) and pass all
                  of the global values in one call. You can pass the address of the
                  structure and use pointers at the DLL end to copy the handle data
                  to GLOBAL values in the DLL.

                  It will depend how you call the DLL. If you load it at startup in
                  the normal manner, this approach works fine, loading the DLL dynamically
                  with LoadLibrary() GetProcAddress() will be a bit slower because
                  of the overhead of having to copy the handle at each instance that
                  it is run but there is probably no other way to do it with the
                  architecture that you need.

                  In one of my editors, I support plugin DLLs and these pass 5 handles
                  to each DLL that is called so that it allows the DLL to operate
                  on a number of internal capacities in the editor and I pass them
                  as normal parameters but if you have a larger number ofr handles to
                  pass, a structure is probably the best way to do it.

                  Regards,

                  [email protected]

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

                  www.masm32.com

                  Comment


                  • #10
                    Thanks everybody for these fast responses.

                    For know I think I'll go the direction that Lance and Steve pointed me
                    out. Actually I was already playing with it after Edwin gave
                    me the pointer hint.

                    Lance,
                    you're right about not to use disk files, its clumsy especially
                    when you allow multiple copies of the app to run

                    Steve
                    Yes, I could do something like
                    Type LargeUDT
                    a as App_Global_Data
                    b as ctl_Global_Data
                    ...
                    End Type
                    Dim x as LargeUDT

                    and then...

                    Call MyDLLSub (varptr(x))

                    and so forth.

                    Now it's up to me to choose

                    I also took a look at the Memory Mapped files but that's over
                    the top for something that could be done much easier.

                    As always there are many roads that lead to Rome...

                    Anyway, thanks alot !

                    Steve



                    ------------------
                    So here we are, this is the end.
                    But all that dies, is born again.
                    - From The Ashes (In This Moment)

                    Comment


                    • #11
                      Steven,

                      I just finished doing this same thing while chopping my program
                      in half so that it would continue compiling.

                      I passed a DWORD array of data_array(0) addresses to the DLL via an
                      initialization function. Then, in the DLL, I DIMed GLOBAL arrays
                      at the same addresses. Works great.

                      ------------------
                      Bernard Ertl

                      [This message has been edited by Bern Ertl (edited June 06, 2001).]
                      Bernard Ertl
                      InterPlan Systems

                      Comment


                      • #12
                        Originally posted by Steven Pringels 3:
                        Yes, I could do something like
                        Type LargeUDT
                        a as App_Global_Data
                        b as ctl_Global_Data
                        ...
                        End Type
                        Dim x as LargeUDT

                        and then...

                        Call MyDLLSub (varptr(x))
                        Taking the pointer concept a little further, I'd be inclined to make those members all pointers and reference them that way, although you'd still have to go thorough the process of filling them with the VARPTR() of the actual UDT's. However, if you modify your code to reference the one big UDT instead of the individual ones, then the big UDT approach would be the most optimium solution.

                        An individual UDT can be up to 64Mb in size, so there is plenty of room to build a large UDT (!), however, LOCAL UDT's are created on the stack frame, so this will limit a LOCAL UDT to something less than 1Mb.

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

                        Comment

                        Working...
                        X