Announcement

Collapse
No announcement yet.

Question on Global variables in a DLL

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

    #21
    Follow-on question, what about pointers? Could a pointer inside the MAIN be passed to a DLL and the reference remain faithful?
    Since you do not pass anything to a DLL, I assume you mean a "Function which is loaded from a DLL."

    Has maybe been answered indirectly but:

    Yes. A pointer value obtained in any process is valid anywhere within that process; but only in that process. However, you may use it in another process using the ReadProcessMemory() WinAPI function, https://learn.microsoft.com/en-us/wi...dprocessmemory

    Also, an easy way to think about this "GLOBAL" thing is, the PB scope words LOCAL, STATIC, GLOBAL and THREADED* create variables with that scope only valid within the module being compiled. That is, those scope statements are used only at compile time.

    * automatically GLOBAL in scope
    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]
    http://www.talsystems.com

    Comment


      #22
      Mike, Stuart, Dale,
      I started this thread a couple of years ago...
      Suppose I have two arrays of the same size and same type. The Good Old Fashioned way to copy an array would be a FOR/NEXT loop, copying each element one-by-one. It works fine. But I'm using multi-dimensional arrays, and the result is a bunch of nested loops that are slow and ugly. I was disappointed to see that ARRAY COPY does


      Lots of suggestions and work-arounds, but I had hoped for one-line simplicity; e.g.: Array2 = @PointerToArray1

      However, Borje's comment was quite useful: MAT b() = a()

      Pointers are funny. First you hate 'em, then you get used to 'em. Enough time passes, you get so you depend on them. That's institutionalized. I'm an institutional man now. Just like Brooks was.
      Christopher P. Becker
      signal engineer in the defense industry
      Abu Dhabi, United Arab Emirates

      Comment


        #23
        Originally posted by Christopher Becker View Post
        However, Borje's comment was quite useful: MAT b() = a().
        Aas long as you are working with a numeric array. MAT doesn't work with string arrays.


        =========================
        https://camcopng.com
        =========================

        Comment


          #24
          Christopher,

          What is wrong with this macro that works with multi-dimensional numeric and string data?
          It is also one-line.
          Kinda off subject of global array in a DLL.

          Code:
          MACRO CopyArray(A1, A2) = PARSE JOIN$ (a1,BINARY), a2, BINARY
          
          FUNCTION PBMAIN AS LONG
          
           'dimension numeric arrays
           REDIM x1(0,0,0) AS LONG
           REDIM x2(0,0,0) AS LONG
           x1(0,0,0) = 99
           CopyArray (x1(),x2())  'copy multi-dimensional numeric
          
           'dimension string arrays
           REDIM s1(0,0,0) AS STRING
           REDIM s2(0,0,0) AS STRING
           s1(0,0,0) = "99"
           CopyArray (s1(),s2())  'copy multi-dimensional string
          
           ? USING$("(#)(&)",x2(0,0,0),s2(0,0,0)) ' (99) (99)
          
          END FUNCTION



          Comment


            #25
            Mike, I appreciate the reply. I really do. That code will come in handy someday for sure.

            Background: My style of coding is to minimize the use of GLOBALs. In fact, I use them as a last resort.

            Situation: Inside PBMAIN(), I've DIMed and populated a large LOCAL array. Now, I want to refer to elements of that array in SUBs and FUNCTIONs. Ideally (!), it would be great to pass a pointer to the array to SUBs and FUNCTIONs, just as if it were a very large string. Of course, if I pass enough information to the SUB, it's possible to re-create the array. But now we're working with a copy, and not the original. Using GLOBAL is the obvious answer; I was just looking for a pointer solution.

            Yes, off-topic; apologies. It was the idea of visibility into an array from a function that reminded me of my previous problem.
            Christopher P. Becker
            signal engineer in the defense industry
            Abu Dhabi, United Arab Emirates

            Comment


              #26
              Situation: Inside PBMAIN(), I've DIMed and populated a large LOCAL array. Now, I want to refer to elements of that array in SUBs and FUNCTIONs. Ideally (!), it would be great to pass a pointer to the array to SUBs and FUNCTIONs, just as if it were a very large string. Of course, if I pass enough information to the SUB, it's possible to re-create the array. But now we're working with a copy, and not the original. Using GLOBAL is the obvious answer; I was just looking for a pointer solution.
              You can do that... or you can just just pass a reference to the array or the the array and and a subscript.

              That is, instead of

              Code:
                 CALL SupportingFunction  (array_element)  or "Pointer to array element" or "big block of data"
              .. you could simply ...
              Code:
                 CALL SupportingFunction  (arrayName() , subscript)
              or
              Code:
                 CALL SupportingFunction  (arrayName() )

              Cases two and three are in essence just passing a reference to the original LOCAL array.

              Isn't that cleaner if you want to work directly with the Array you created?
              Michael Mattias
              Tal Systems (retired)
              Port Washington WI USA
              [email protected]
              http://www.talsystems.com

              Comment


                #27
                Originally posted by Christopher Becker View Post
                Situation: Inside PBMAIN(), I've DIMed and populated a large LOCAL array. Now, I want to refer to elements of that array in SUBs and FUNCTIONs. Ideally (!), it would be great to pass a pointer to the array to SUBs and FUNCTIONs ...
                That's what BYREF does.
                '
                Code:
                #COMPILE EXE
                #DIM ALL
                FUNCTION PBMAIN() AS LONG
                    LOCAL lDebug AS LONG: TXT.WINDOW EXE.FULL$, 10,10,45,85 TO lDebug
                    DIM StrMyArray(10 TO 20) AS STRING
                    StrMyArray(15) = "Fifteen"
                    AccessStrArray(strMyArray())
                    TXT.PRINT "Back from Function, strMyArray(20) = ", strMyArray(20)
                'Finalise
                    TXT.COLOR = %RGB_BLUE
                    TXT.PRINT
                    TXT.PRINT "  ....Press any key to exit": TXT.WAITKEY$: TXT.END
                END FUNCTION
                
                FUNCTION AccessStrArray(BYREF strA() AS STRING) AS LONG
                    TXT.PRINT "In Function - Lbound=", LBOUND(strA())
                    TXT.PRINT "In Function - Ubound=", UBOUND(strA())
                    TXT.PRINT "In Function  strMyArray(15) = ",strA(15)
                    strA(20) = "Twenty"
                END FUNCTION
                '

                Click image for larger version  Name:	PassArray.jpg Views:	0 Size:	35.8 KB ID:	823522
                =========================
                https://camcopng.com
                =========================

                Comment


                  #28
                  Read, write arrays to disk or call DLLLoadGlobal to load string array into gs() in the DLL
                  Array can be local, threaded or global.
                  Code:
                  #DIM ALL      'ReadWriteArray.bas
                  '%MakeEXE = 1 'remark to create DLL then unremark to test
                  
                  #IF %DEF(%MakeEXE)
                   #COMPILE EXE
                   DECLARE FUNCTION WriteArray    LIB "MyDLL.DLL" (sFileName AS STRING,temparr() AS STRING,ecode AS LONG) AS LONG
                   DECLARE SUB      DllLoadGlobal LIB "MyDLL.DLL" (sFileName AS STRING)
                   DECLARE FUNCTION ReadArray     LIB "MyDLL.DLL" (sFileName AS STRING,temparr() AS STRING,ecode AS LONG) AS LONG
                  
                   FUNCTION PBMAIN AS LONG
                    LOCAL ecode AS LONG
                    REDIM s(1) AS STRING
                    s(0) =        "Saved to disk and"
                    s(1) =        "loaded into DLL global array"
                    WriteArray    "temp.txt",s(),ecode&
                    DllLoadGlobal "temp.txt"  'calls ReadArray and fills gs() array in DLL
                   END FUNCTION
                  '====================================================================================================================
                  
                  #ELSE 'DLL
                   #COMPILE DLL "MyDll.Dll"
                   GLOBAL gs() AS STRING
                  
                   FUNCTION WriteArray(sFileName AS STRING,temparr() AS STRING,ecode AS LONG) EXPORT AS LONG
                    LOCAL hFile AS LONG
                    hfile = FREEFILE
                    OPEN sFileName FOR OUTPUT AS #hfile
                    IF ERR THEN ecode = ERR:FUNCTION = ecode:BEEP:EXIT FUNCTION
                    PRINT #hFile, temparr()
                    IF ERR THEN ecode = ERR:BEEP:FUNCTION = ERR
                    CLOSE #hfile
                   END FUNCTION
                  
                   FUNCTION ReadArray(sFileName AS STRING,temparr() AS STRING,ecode AS LONG) EXPORT AS LONG
                    LOCAL hFile    AS LONG
                    LOCAL elements AS LONG
                    ERASE temparr
                    IF ISFILE(sFilename) THEN
                     hfile = FREEFILE
                     OPEN sFileName FOR INPUT AS #hfile
                     IF ERR THEN ecode = ERR:FUNCTION = ecode:BEEP:EXIT FUNCTION
                     FILESCAN #hfile, RECORDS TO elements
                     IF elements < 1 THEN ECODE = -1:FUNCTION = ecode:BEEP:CLOSE #hfile:BEEP:EXIT FUNCTION
                     REDIM temparr(1 TO elements)
                     LINE INPUT #hfile, temparr() TO elements
                     IF ERR THEN ecode = ERR:FUNCTION = ecode:BEEP
                     CLOSE #hfile
                    ELSE
                     ecode = 53:FUNCTION = ecode
                    END IF
                   END FUNCTION
                  
                   SUB DllLoadGlobal(sFileName AS STRING) EXPORT
                    LOCAL ecode AS LONG
                    ReadArray sFileName,gs(),ecode
                    ? JOIN$(gs(),$CRLF),,"DLL Load Global"
                   END SUB
                  #ENDIF

                  Comment

                  Working...
                  X
                  😀
                  🥰
                  🤢
                  😎
                  😡
                  👍
                  👎