Announcement

Collapse
No announcement yet.

Static Link Libraries - BYCOPY and other questions

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

  • Static Link Libraries - BYCOPY and other questions

    Hello PowerBasic DieHards! To attempt to solve the big program "cannot access compiler results" problem we've been discussing on another thread, I am trying to teach this old dog a new trick: SLL. As a test, I pulled some of my number formatting routines out to a new file, sample below (cut way down for illustration):

    compile SLL "RDSwinSLL.sll"
    FUNCTION FMTnums7$(X!) AS STRING
    IF ABS(X!)>=.0000001 THEN AA$=FORMAT$(X!,"* #0.####") ELSE AA$=" 0.0 "
    FUNCTION=AA$
    END FUNCTION

    This compiled fine. I deleted that code in the main program and added [#LINK "RDSwinSLL.sll"] at the same place. When I try to compile it goes to another part of the code and gives Sytax Error 477, pointing to BYCOPY in this line:

    dum$ = FMTnums7$( BYCOPY (FixMiceX(x0)) )

    BYCOPY was required to get that routine to work in the first place, since it is passing the results of another Function, FixMiceX().

    Apparently BYCOPY is not allowed for a SLL Function? Is there a workaround? Maybe something in the compile of the SLL? Or will I have to use something like:

    Xduh=FixMiceX(x0)
    dum$ = FMTnums7$( Xduh )

    That'll take a while - 100k+ lines of code.....

  • #2
    Thought of something else - maybe it is not allowed to use another Function in a SLL Function unless it is included in the same compile?

    Ouch - that would really limit the routines I could move to SLL.

    Comment


    • #3
      I have had sporadic issues over the years with trying to pass a function expression to another function.

      So instead of

      Code:
      dum$ = FMTnums7$( BYCOPY (FixMiceX(x0)) )
      I'd suggest first getting the result of FixMiceXI() into a variable, then passing that variable..

      Code:
      MyArg = FixMiceX(x0)
      dum$ = FMTnums7$( BYCOPY MyArg )    ' << ByCopy will only be needed if MyArg is NOT the same datatype as the argument of FMTnums7$ (THIS_DATANAME_TYPE) which is SINGLE.
      Don't whine about an extra step messing up performance because this is exactly what the compiler is doing transparently in the one, more complex, source code line anyway.

      Besides, if you find it necessary to use the stepping debugger, you will want to track the value of myArg.

      MCM





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

      Comment


      • #4
        Also
        Thought of something else - maybe it is not allowed to use another Function in a SLL Function unless it is included in the same compile?
        Ouch - that would really limit the routines I could move to SLL.
        It should not compile unless the function is "known" to the function being compiled; but I cannot find anything in the help about using externals within an SLL. (In a DLL you can just DECLARE it).

        [EDITORIAL OPINION]
        However, your libraries should be full of discrete routines usable by many programs, and dependent only on itself - that is, any support functions required should be in that same code module - to make it truly a "reuseable library."
        [/EDITORIAL OPINION]

        I do not believe your "cannot access compiler results" error has anything to do with the size of the code being compiled. Bundle it up and send it to PB or a colleague with the same compiler version and see what happens.

        That is, moving code to an SLL or DLL should not be used to overcome this particular problem. At least not IMNSHO.
        MCM
        Michael Mattias
        Tal Systems (retired)
        Port Washington WI USA
        [email protected]
        http://www.talsystems.com

        Comment


        • #5
          Hi Michael,

          Thanks for taking the time to reply. My code is not only huge, it also uses Eric Pearson's excellent Contools/GFX package. Eric no longer sells or supports it, and I doubt that PB has it or would want to mess with it. It would take me weeks to make a compileble code that doesn't reference it, and removing so much code would probably fix the "Cannot Access" problem. Just taking out a few hundred lines of code fixes it right now.

          If any more things to check occur to you, I would sure appreciate it!

          Dan

          Comment


          • #6
            Not really seeing enough of your code to know for sure but a couple of guesses.
            First, though, I always put # Link statements near the start of the program where the $INCLUDEs are usually placed.
            FUNCTION FMTnums7$(X!) AS STRING
            should be
            FUNCTION FMTnums7$(X!) COMMON AS STRING
            when you compile your SLL.

            I don't think I've ever seen BYCOPY used in a call to a function, but only in a FUNCTION/SUB definition or declaration.

            Could you post all the code in the SLL so we could give better assessment.
            Using other subs or functions is okay in an SLL, but if you're calling a sub or function that isn't in the SLL it needs to be declared in the SLL.
            Rod
            In some future era, dark matter and dark energy will only be found in Astronomy's Dark Ages.

            Comment


            • #7
              > FUNCTION FMTnums7$(X!) AS STRING

              The function is not visible outside of the SLL unless it
              FUNCTION FMTnums7$(X!) COMMON AS STRING

              In fact, if it neither COMMON nor called by other code in the SLL, it will probably be removed from the SLL by "dead code removal"

              Comment


              • #8
                Originally posted by Daniel Raymer View Post
                dum$ = FMTnums7$( BYCOPY (FixMiceX(x0)) )

                BYCOPY was required to get that routine to work in the first place, since it is passing the results of another Function, FixMiceX().

                Apparently BYCOPY is not allowed for a SLL Function? Is there a workaround? Maybe something in the compile of the SLL? Or will I have to use something like:
                There's nothing wrong with the BYCOPY. In fact the explicit BYCOPY was not required there.
                The brackets around FixMiceX(x0) forces the BYCOPY automatically.

                From Help -> CALL
                Another way to force BYCOPY is to enclose a variable name in parentheses, so it will appear to the compiler as an expression, rather than just a single variable.
                Unless declared otherwise, parameters default to BYREF passing method. Expressions and constants are always passed BYCOPY.

                Comment


                • #9
                  OK, I got the SLL approach to work, allowing me to pull out about 200 lines of code. This fixed the "Cannot Access..." error - at least for now.

                  I only got the SLL to work because Stuart and Rodney pointed out that I didn't put Common in the SLL Functions. I need to read the instructions more carefully!

                  Comment


                  • #10
                    I don't think I've ever seen BYCOPY used in a call to a function, but only in a FUNCTION/SUB definition or declaration.
                    BYCOPY is a lot like BYVAL, except you pass the address of a copy of the variable instead of a copy of the value of the variable.

                    You might use BYCOPY if you want to modify a passed variable but only within the called procedure and not affect the original variable.

                    No, I don't write like that.

                    OR, you can use BYCOPY to pass a variable of a different datatype .. lets say its some library function expecting a param by reference but that reference has to be a different datatype from what you want to pass.

                    No, I don't write like that, either.

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

                    Comment


                    • #11
                      The only difference you will find between using an SLL module and the same code in a normal basic file is the SLL code cannot SEE global values unless they are specifically passed to it. Everything else is the same, pass by value, pass by reference, the second being the ADDRESS of a variable or structure, passed by value. BYREF is actually a convenience that saves the programmer from having to get the address first THEN passing it by value.
                      hutch at movsd dot com
                      The MASM Forum - SLL Modules and PB Libraries

                      http://www.masm32.com/board/index.php?board=69.0

                      Comment


                      • #12
                        Thanks Michael!
                        Rod
                        In some future era, dark matter and dark energy will only be found in Astronomy's Dark Ages.

                        Comment


                        • #13
                          My apologies to Eric Pearson for saying "Eric no longer sells or supports it." He no longer sells it, which is a shame because his DLLs are what make PBCC a thing of beauty, at least for my applications. But Eric has continued to answer questions and offer help and suggestions (ie., support), even though it has been years since I bought those DLLs from him. Thanks Eric, sorry if I offended you by my offhand wording. I'm clumsy that way, like a lot of people who spend way too much time in front of a computer. Cheers! /Dan

                          Comment


                          • #14
                            No offense taken, Dan! I appreciate how incredibly loyal you have been, I just wanted to be clear for casual readers.

                            Fact is, I don't think I've ever even run a Console Tools program on a Windows 10 computer, and that's scary, support-wise. It was originally written for Windows NT and especially Windows 95/98 because the Platform 1 console window was such a mess, and each version of Windows threw curveballs.
                            "Not my circus, not my monkeys."

                            Comment


                            • #15
                              The only difference you will find between using an SLL module and the same code in a normal basic file is the SLL code cannot SEE global values unless they are specifically passed to it.
                              There is one other little item and that is UDTs. The have to be declared in both the SLL code and the main application's calling code. Most UDTs will be caught by including the WinAPI.inc in the SLL code, but if the UDT is only used in the SLL andor is used as a parameter one can't call the SLL unless the TYPE has been declared in the calling code.
                              Rod
                              In some future era, dark matter and dark energy will only be found in Astronomy's Dark Ages.

                              Comment


                              • #16
                                Originally posted by Rodney Hicks View Post
                                There is one other little item and that is UDTs. The have to be declared in both the SLL code and the main application's calling code. Most UDTs will be caught by including the WinAPI.inc in the SLL code, but if the UDT is only used in the SLL andor is used as a parameter one can't call the SLL unless the TYPE has been declared in the calling code.
                                That's a confusing statement. "only" and "andor" used together doesn't make sense.

                                The UDT only needs to be declared in the main application if a variable of that type is actually used in the main application (either within a sub/function in the main application code OR as a parameter to a COMMON sub/function in the SLL). If it is not used directly in the main application code, it doesnt need to be declared

                                THis works fiine without declaring the TYPE in the main application:
                                '
                                Code:
                                #COMPILE SLL "SLL_UDT_Test.SLL"
                                TYPE myType
                                    txt AS STRING * 32
                                    num AS LONG
                                END TYPE
                                
                                FUNCTION Test() COMMON AS STRING
                                   LOCAL mt AS myType
                                   LOCAL hDlg  AS DWORD
                                   mt.txt = "ABC"
                                   FUNCTION = mt.txt
                                END FUNCTION
                                '
                                '
                                Code:
                                #COMPILE SLL "SLL_UDT_Test2.SLL"
                                TYPE myType
                                    txt AS STRING * 32
                                    num AS LONG
                                END TYPE
                                
                                FUNCTION Test2() COMMON AS STRING
                                   LOCAL hDlg  AS DWORD
                                   FUNCTION = test3
                                END FUNCTION
                                
                                FUNCTION Test3() AS STRING
                                    LOCAL mt AS myType
                                    mt.txt = "DEF"
                                    FUNCTION = mt.txt
                                END FUNCTION
                                '
                                '
                                Code:
                                #COMPILE EXE
                                #LINK "SLL_UDT_test.SLL"
                                #LINK "SLL_UDT_test2.SLL"
                                FUNCTION PBMAIN() AS LONG
                                     ? Test
                                     ? Test2
                                END FUNCTION
                                 '


                                Comment


                                • #17
                                  Rod,

                                  Its normal coding practice to pass a UDT (structure) by its address from the caller and the SLL must use the same UDT at the receiving end. If you know how to do it, you can pull it apart at the receiving end in assembler but why bother, PB handles structures just fine.
                                  Code:
                                  ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
                                  
                                      #compile sll
                                  
                                      TYPE RECT
                                        nLeft   AS LONG
                                        nTop    AS LONG
                                        nRight  AS LONG
                                        nBottom AS LONG
                                      END TYPE
                                  
                                  ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
                                  
                                  FUNCTION CvtRct(rct as RECT) COMMON as DWORD
                                  
                                      rct.nRight = rct.nRight - rct.nLeft
                                      rct.nBottom = rct.nBottom - rct.nTop
                                  
                                   End FUNCTION
                                  
                                  ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
                                  hutch at movsd dot com
                                  The MASM Forum - SLL Modules and PB Libraries

                                  http://www.masm32.com/board/index.php?board=69.0

                                  Comment


                                  • #18
                                    That's a confusing statement. "only" and "andor" used together doesn't make sense.
                                    Does this help?
                                    Code:
                                    #COMPILE SLL
                                    #DIM ALL
                                    
                                    TYPE gotcha
                                      jj AS LONG
                                      kk AS LONG
                                    END TYPE
                                    
                                    FUNCTION got_it(something AS LONG, somethingelse AS gotcha) COMMON AS LONG
                                      LOCAL lostit AS LONG
                                      lostit=something * somethingelse.jj
                                      lostit=lostit/somethingelse.kk
                                      FUNCTION = lostit
                                    END FUNCTION
                                    Rod
                                    In some future era, dark matter and dark energy will only be found in Astronomy's Dark Ages.

                                    Comment


                                    • #19
                                      Originally posted by Rodney Hicks View Post
                                      Does this help?
                                      Code:
                                      #COMPILE SLL
                                      #DIM ALL
                                      
                                      TYPE gotcha
                                      jj AS LONG
                                      kk AS LONG
                                      END TYPE
                                      
                                      FUNCTION got_it(something AS LONG, somethingelse AS gotcha) COMMON AS LONG
                                      LOCAL lostit AS LONG
                                      lostit=something * somethingelse.jj
                                      lostit=lostit/somethingelse.kk
                                      FUNCTION = lostit
                                      END FUNCTION
                                      Normally, you would be passing a UDT as a parameter in your main code , so obviously the main code MAY have to know about its structure in order to read or write to its members - in which case you need a TYPE declaration in your main code.
                                      If you call that function! But even then, not necessarily.
                                      '
                                      Code:
                                      #COMPILE SLL "SLL_UDT_Test3.SLL"
                                      TYPE myType
                                          num AS LONG
                                          txt AS STRING * 32
                                      END TYPE
                                      
                                      FUNCTION Test() COMMON AS STRING
                                         FUNCTION = "ABC"
                                      END FUNCTION
                                      
                                      FUNCTION TestUDT(mt AS myType) COMMON AS STRING
                                          FUNCTION = mt.txt
                                      END FUNCTION
                                      '
                                      '
                                      Code:
                                      #COMPILE EXE "SLL_UDT_test2"
                                      #LINK "SLL_UDT_Test3.SLL"
                                      FUNCTION PBMAIN() AS LONG
                                           ? Test()
                                           ? TestUDT("01234567890")
                                      END FUNCTION
                                      '
                                      Last edited by Stuart McLachlan; 9 May 2022, 10:16 PM.

                                      Comment


                                      • #20
                                        You may also pass information to the SLL with a UDT that the SLL uses to create more information. An example would be passing sidea, angle, sideb to a function that calculates the missing components of a triangle and returns the results in a UDT, such UDT would have to be declared in the calling code as well. Such an SLL would have a dependency external to the SLL. There are other ways of doing the same, but I brought the subject up because it does require a little extra.
                                        Rod
                                        In some future era, dark matter and dark energy will only be found in Astronomy's Dark Ages.

                                        Comment

                                        Working...
                                        X