Announcement

Collapse
No announcement yet.

Static Link Libraries - BYCOPY and other questions

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

  • Dale Yarker
    replied
    Oops.

    in SLL or DLL for GLOBAL in EXE code:

    GLOBAL gpMyNumber AS LONG PTR 'for example
    SUB SetGlobal(BYVAL LP AS LONG PTR) COMMON (or EXPORT)
    gpMyNumber = LP
    END SUB

    in EXE code:
    GLOBAL A_Number AS LONG
    probably in MAIN()
    SetGlobal(VARPTR(A_Number))
    Last edited by Dale Yarker; 12 May 2022, 07:15 PM.

    Leave a comment:


  • Michael Mattias
    replied
    and pointer of original global is passed, then the other module can access the value with @ or PEEK/POKE.
    And how do you pass that pointer? You pass the variable by reference to a PROCEDURE

    There actually is another way, which is to create a named memory object e.g.,,

    Code:
    #COMPILE SLL
    
    $OBJECT_NAME = "ABCDEFG"
    %OBJECT_SIZE  =  1028&
    
    FUNCTION CreateMMF ()
    
    LOCAL szFileName AS ASCIIZ * %MAX_PATH
    
    szFileName =  $OBJECT_NAME
    
         hFileMapping     = CreateFileMapping (%INVALID_HANDLE_VALUE,  BYVAL %NULL, %PAGE_READWRITE , %NULL, %OBJECT_SIZE, szFileName)
    
         Put some values into the mapped object
         DO NOT CLOSE THE HANDLE
    
    END FUNCTION
    Now in your main program, after calling the CreateMMF() function (procedure) in the SLL you can simply "OpenFileMapping" or even "CreateFileMapling" using the same $OBJECT NAME.

    It would not be too dissimilar from sharing memory this way across processes, as demo'd here..

    Win32: Memory Mapped Files/Control User Count April 26, 2001

    Clearly I have not fleshed this out all the way - for example I have not made a provision to close the File Mapping object. But the point is, you could create a reuseable library to share memory using any of the mechanisms which are used to share memory across processes. Or for that matter, sharing across threads using Thread Local Storage.


    MCM

    Leave a comment:


  • Dale Yarker
    replied
    Thread subject was solved.

    More interesting (to me at least) is use of GLOBALs between EXE, DLL(s) or SLL(s).

    Someone might be tempted to declare a global with the same variable name and expect the value to be shared between modules. As noted already, it won't of course.

    But if in another module a GLOBAL pSameName AS whatevertype PTR
    and pointer of original global is passed, then the other module can access the value with @ or PEEK/POKE.

    Cheers,

    Leave a comment:


  • Steve Hutchesson
    replied
    Outside of the normal binary isolation (caller cannot see inside an SLL and an SLL cannot see inside its caller, what's the difference between a calling source and the contents of an SLL ?

    A rhetorical question, there isn't any. They are both basic code and as long as you don't mix compiler specific code (PBWIN versus PBCC specific code), you do the normal things where visibility across files is not available, you make sure that data passed to the SLL as arguments can be read by the SLL and if its a structure (UDT) or any other data type, you must have either the prototypes (declarations) or data types defined in both caller and SLL.

    This has been normal technology with libraries for a very long time across different brands and compiler/assembler types.

    Leave a comment:


  • Dale Yarker
    replied
    Over discussion of obvious???? (running since post 15, or about half the trad.)

    For every separate compile to EXE, DLL or SLL the compiler needs to know the "construction" of the variable types used and/or passed.

    "Construction" of LONGs, DWORDs, STRINGs, etcetera, etcetera is built into the compiler. By definition the "construction" of User Defined Types (UDTs) is not built into the compiler. Therefore, every separately compiled module must have a TYPE/END TYPE for every UTD variable(s) type used in that module.

    Leave a comment:


  • Kurt Kuzba
    replied
    Originally posted by Rodney Hicks View Post
    My point was that a UDT created for some SLL that returns results to the main program via that UDT also has to be defined in the main program. For UDTs included in the compiler it is not necessary, and most others can be included by $INCLUDEing the WinAPI32.inc.
    Your point is correct.
    Have you tried to compile as SSL with an undefined UDT being used?
    It won't compile, will it?
    So, you cannot pass a UDT, that the SSL doesn't use or know about, and expect it to work properly.

    Leave a comment:


  • Rodney Hicks
    replied
    Actually, the two TYPE definitions used in the PROCEDURE have to be included in the main program so the PROCEDURE can be accessed from the main program.
    They are used in the PROCEDURE(chicken) in the SLL(egg). You can't get into the SLL to call the PROCEDURE without the TYPE definitions.Facetious or what?
    Precompiled SLLs can contain COMMON SUBS and FUNCTIONs, and COMMON CLASSES and OBJECTS according to the documentation. See
    Creating a Static Link Library
    The TRIANGLE udt returns 9 values, the length of the three sides, the three angles in both degrees and radians so three doubles aren't enough, but yes, it could have been done differently.

    Leave a comment:


  • Michael Mattias
    replied
    The two TYPE definitions from this SLL have to be included in the main program so the SLL can be accessed from the main program even though this code compiles as an SLL.
    Actually, the two TYPE definitions used in the PROCEDURE have to be included in the main program so the PROCEDURE can be accessed from the main program.

    Well, actually, were the procedure defined such that you don't need the TRIANGLE structure and instead used three DOUBLE precesion variables (the members) instead of the structure, you would not need the TRIANGLE structure in the main program and your library procedure would be more portable.

    Precompiled code - EXE's, DLLs and SLLs - contain only procedures.

    Leave a comment:


  • Rodney Hicks
    replied
    Once compiled, there is no difference between a linked procedure and one in the compiled source.
    They do lack references to UDTs defined in the source, but if they are UDTs also used by the SLL,
    then they will already be defined within that source code.
    My point was that a UDT created for some SLL that returns results to the main program via that UDT also has to be defined in the main program. For UDTs included in the compiler it is not necessary, and most others can be included by $INCLUDEing the WinAPI32.inc.
    An example:
    Code:
    #COMPILE SLL
    #DIM ALL
    
    TYPE SIDEANGLE
      length    AS DOUBLE
      oppangle  AS DOUBLE
      opprdns   AS DOUBLE
    END TYPE
    
    TYPE TRIANGLE
      A AS SIDEANGLE
      B AS SIDEANGLE
      C AS SIDEANGLE
    END TYPE
    
    DECLARE FUNCTION Radians(angleindegrees AS DOUBLE) COMMON AS DOUBLE
    
    SUB AngleSideAngle(ang1 AS DOUBLE, leng AS DOUBLE, ang2 AS DOUBLE, tasa AS TRIANGLE) COMMON
      tasa.A.oppangle   = ang1
      tasa.A.opprdns    = Radians (ang1)
      tasa.B.oppangle   = ang2
      tasa.B.opprdns    = Radians (ang2)
      tasa.C.oppangle   = 180- tasa.A.oppangle- tasa.B.oppangle
      tasa.C.opprdns    = Radians (tasa.C.oppangle)
      tasa.C.length     = leng
      tasa.A.length     = tasa.C.length/SIN(tasa.A.opprdns)/SIN(tasa.C.opprdns)
      tasa.B.length     = tasa.C.length/SIN(tasa.B.opprdns)/SIN(tasa.C.opprdns)
    END SUB
    The two TYPE definitions from this SLL have to be included in the main program so the SLL can be accessed from the main program even though this code compiles as an SLL.

    Leave a comment:


  • Kurt Kuzba
    replied
    Originally posted by Stuart McLachlan View Post

    Pedantry? It's like quibbling that you don't store a file on a disk, you store it in a directory
    It is a point, though.
    Once compiled, there is no difference between a linked procedure and one in the compiled source.
    They do lack references to UDTs defined in the source, but if they are UDTs also used by the SLL,
    then they will already be defined within that source code.
    That really is the entire idea behind linked libraries, that they function the same as your compiled source.
    It may be a level of understanding not required for most users, of course.

    Leave a comment:


  • Steve Hutchesson
    replied
    I would be far more interested is seeing some published SLL modules than waffle about how they should be written. With all the noise, the yield is very small, when will someone deliver ?

    Hmmmm, I wonder what happened to my signature ? Aha, its turned up again.

    Leave a comment:


  • Stuart McLachlan
    replied
    Originally posted by Rodney Hicks View Post
    Define 'information'. Are values not information? Are they not going to the SLL?
    Pedantry? It's like quibbling that you don't store a file on a disk, you store it in a directory

    Leave a comment:


  • Rodney Hicks
    replied
    Define 'information'. Are values not information? Are they not going to the SLL?

    Leave a comment:


  • Michael Mattias
    replied
    You do NOT "pass information to a SLL" (or DLL for that matter).

    You DO pass information to Procedures ( or interface METHODs).

    Leave a comment:


  • Rodney Hicks
    replied
    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.

    Leave a comment:


  • Stuart McLachlan
    replied
    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.

    Leave a comment:


  • Rodney Hicks
    replied
    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

    Leave a comment:


  • Steve Hutchesson
    replied
    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
    
    ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    Leave a comment:


  • Stuart McLachlan
    replied
    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
     '


    Leave a comment:


  • Rodney Hicks
    replied
    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.

    Leave a comment:

Working...
X