Announcement

Collapse
No announcement yet.

A Question About DLL's

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

  • A Question About DLL's

    How can I use the same technique that Microsoft's DLL's use
    when one of their functions can use different types of variables
    for the same argument? In other words, if their function has
    an argument declared as AS ASCIIZ, you may also use BYVAL Number&.
    How can a DLL function KNOW which type of argument it is, without
    GPFing? I'd like to use the technique in some of my custom DLL's.

    Thanks in advance!


    ------------------
    Clay C. Clear

    Clay Clear's Software
    mailto:[email protected][email protected]</A>

  • #2
    Clay,

    I am reasonably sure that within the definition of an industry standard
    DLL that it cannot be done. PowerBASIC produces DLLs that conform
    to that standard so it currently does not have that capacity in a
    direct manner.

    There are a number of ways to do what you are after but none of them
    are easy to code manually, if you dont mind the extra overhead, you
    can pass different size data in a union but there is no native way
    of automatically determining at the other end which data type is being
    passed.

    You could manually code an extra variable that passed this info to
    the function in the DLL so that it could tell what is being passed to
    it but this is different to the process used in Microsoft languages where
    this is built in at the compiler level.

    To do what you are after in an efficient manner, I would be inclined to
    write a major function in the DLL and make a set of calling functions
    that can accept different parameter sizes and types. Each calling
    function will have to handle the different data correctly and then
    call the major function.

    Regards,

    [email protected]

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

    www.masm32.com

    Comment


    • #3
      Clay --

      When you pass an ASCIIZ string to a function you are actually passing a 4-byte pointer (a DWORD) -- a numeric value -- that tells the function where the string is located. When you use BYVAL x the PowerBASIC compilers override their usual type-checking and allow you to pass a literal number. You can also use BYVAL STRPTR(sString$) to pass a "normal" string instead of an ASCIIZ string. It's the BYVAL that allows you to use something other than the declared parameter type. (You can also declare the parameter AS ANY, to tell the compiler "a pointer to some type of variable will be passed for this parameter" but that practice is usually discouraged.)

      So all you really have to do in your function is to always treat the incoming parameter as a number. For example, your function could have a parameter that is BYVAL lPointer AS LONG (or BYVAL lPointer&), but in the declaration for the function -- the DECLARE line that is used by programs that want to call the function -- declare it as zValue AS ASCIIZ.

      Then if the calling program uses BYVAL 0 the value of lPointer (received by the function) will be zero. If they use an ASCIIZ string then lPointer will be nonzero, and the function can use it to find the string.

      A good knowlege of pointers, using DIM...AS...PTR, the @ operator, and related topics will be helpful, but it's not all that difficult.

      -- Eric


      ------------------
      Perfect Sync Development Tools
      Perfect Sync Web Site
      Contact Us: mailto:[email protected][email protected]</A>



      [This message has been edited by Eric Pearson (edited October 03, 2001).]
      "Not my circus, not my monkeys."

      Comment


      • #4
        This is probably a pretty rude way of doing it, but how about passing a single parameter - a string (but not asciiz) like this:
        "S4:fredI01"
        where S means string, it then reads until the ":" to find the length of the string - 4 bytes, so it reads the next 4 bytes in which it knows is a string - "fred"
        It then moves onto the next byte which it knows will be a "type identifier" (such as S for string, I for Integer, L for Long etc). It sees that the second type in this case is an integer, and knows that Integers are 16-bit, so it reads the next 2 bytes in and assigns that to a local integer variable. etc etc...

        Best of luck,
        Wayne


        [This message has been edited by Wayne Diamond (edited October 03, 2001).]
        -

        Comment


        • #5
          How can I use the same technique that Microsoft's DLL's use
          when one of their functions can use different types of variables
          for the same argument? In other words, if their function has
          an argument declared as AS ASCIIZ, you may also use BYVAL Number&.
          Many curious things are hidden in the Windows APIs. The technique
          to which you refer is somewhat unsavory, but readily duplicated.
          A number of APIs allow you to pass either an ASCIIZ string or a
          word value in a LONG or DWORD. They can tell the difference because
          the high word (of the LONG or DWORD) is always going to be zero if
          you're passing a word, which will never be true if the value is an
          ASCIIZ pointer.

          If you were to write such a routine, it would look something like:
          Code:
          SUB marine (BYVAL nParam AS DWORD)
           
              LOCAL wValue AS WORD
              LOCAL pszValue AS ASCIIZ PTR
           
              IF HIWRD(nParam) THEN
                  pszValue = nParam
                  MSGBOX "String: " + @pszValue
              ELSE
                  wValue = nParam
                  MSGBOX "Number: " + FORMAT$(wValue)
              END IF
           
          END SUB
          ------------------
          Tom Hanlin
          PowerBASIC Staff

          Comment


          • #6
            Tom,

            Wouldn't you also be restricted to passing only a positive word?

            ------------------

            Comment


            • #7
              A WORD is always non-negative. You could just as easily pass an INTEGER,
              though, as long as you encode and decode it properly, e.g.,

              marine BYVAL MAKDWD(integervalue%, 0)

              ...and make wValue an INTEGER instead of a WORD in marine.


              ------------------
              Tom Hanlin
              PowerBASIC Staff

              Comment


              • #8
                Thanks for your replies, folks! I've got the info I need, now.

                Thanks, again.

                Regards,


                ------------------
                Clay C. Clear

                Clay Clear's Software
                mailto:[email protected][email protected]</A>

                Comment


                • #9
                  If you suspect the value is a pointer and dont want to GPF then you can use the following function
                  DECLARE FUNCTION IsBadWritePtr LIB "KERNEL32.DLL" ALIAS "IsBadWritePtr" (BYVAL lp AS LONG, BYVAL ucb AS LONG) AS LONG
                  lp is memory address, ucb is size of memory in bytes to check (should be at least 1).
                  Returns 0 if valid pointer


                  ------------------

                  Comment

                  Working...
                  X