Announcement

Collapse
No announcement yet.

Pointer vs Variable in API

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

  • Pointer vs Variable in API

    I've often used functions by just copying working code I saw someone else use. But then occasionally I find something in MSDN and that makes me wonder why the code worked in the first place.

    The MSDN discussion on GetCursorPos says that the argument is a "Pointer to a POINT structure that receives the screen coordinates of the cursor."

    So why does this work in PowerBASIC

    Code:
    Dim P as Point
    GetCursorPos P
    Instead of this.

    Code:
    Dim P as Point
    GetCursorPos VarPtr(P)
    The Win32API.inc gives a declaration that looks the same for the argument as is given on MSDN.

    Code:
    DECLARE FUNCTION GetCursorPos LIB "USER32.DLL" ALIAS "GetCursorPos" (lpPoint AS POINTAPI) AS LONG

  • #2
    Passing a variable by reference is the same that passing a pointer to that variable by value.
    Forum: http://www.jose.it-berater.org/smfforum/index.php

    Comment


    • #3
      You can declare the function as:

      Code:
      DECLARE FUNCTION GetCursorPos LIB "USER32.DLL" ALIAS "GetCursorPos" (lpPoint AS POINT) AS LONG
      and use:

      Code:
      Dim P as Point
      GetCursorPos P
      or as:

      Code:
      DECLARE FUNCTION GetCursorPos LIB "USER32.DLL" ALIAS "GetCursorPos" (BYVAL lpPoint AS POINT PTR) AS LONG
      and use:

      Code:
      Dim P as Point
      GetCursorPos VARPTR(P)
      Other variations are also allowed, like (using the first declare):

      Code:
      Dim P as Point
      GetCursorPos BYVAL VARPTR(P)
      In all cases, the result is the same: you are passing a pointer (by value) to a POINT structure.
      Forum: http://www.jose.it-berater.org/smfforum/index.php

      Comment


      • #4
        Thanks Jose,

        So if the declaration used ByVal for the argument, like this:

        Code:
        DECLARE FUNCTION GetCursorPos LIB "USER32.DLL" ALIAS "GetCursorPos" (ByVal lpPoint AS POINTAPI) AS LONG
        Then the VarPTR() would have been required?

        Comment


        • #5
          You can't pass a pointer using that declaration. You should use AS POINT PTR or AS POINTAPI PTR (POINT and POINTAPI are the same structure).

          With that declare, you can only pass a POINT structure by value, i.e. pushing all the members of the structure into the stack, not a pointer to the structure.
          Forum: http://www.jose.it-berater.org/smfforum/index.php

          Comment


          • #6
            Jose,

            Thanks for the multiple clarifications.

            For reasons unknown, I had always assumed there was a "single" declaration to an API - as defined by Microsoft.

            It's only been recently, as I get more exposed to PowerBASIC, that I've realized the authors of the Win32API.inc file have options with the Declarations. Your post helps clarify that.

            Comment


            • #7
              Jose,

              That brings up another question. Is it common for programmers to create variations on Declare statements - for convenience or other reasons?

              With your example, showing how its done, is it the case that programmers do use customized Declarations?

              I can't say that I've seen it done, but then I wasn't looking for it.

              I have seen several cases where substitutions such as POINT - POINTAPI were made, where the structures are internally the same.

              Comment


              • #8
                I know that Patrice does it often, but it is not very common because, unless different names are used for the functions it will cause conflicts when sharing code.

                if you use:

                Code:
                DECLARE FUNCTION GetCursorPos LIB "USER32.DLL" ALIAS "GetCursorPos" (BYVAL lpPoint AS POINT PTR) AS LONG
                and you call it as:

                Code:
                DIM p AS POINT
                GetCursorPos VARPTR(p)
                and another guy tries to use your code with an include file where the function is declared as:

                Code:
                DECLARE FUNCTION GetCursorPos LIB "USER32.DLL" ALIAS "GetCursorPos" (lpPoint AS POINT) AS LONG
                the compiler will complain.

                Although, if you use:

                Code:
                DIM p AS POINT
                GetCursorPos BYVAL VARPTR(p)
                it will work with both declares.

                You can also have the two declares, as long as the alias and number of parameters are the same and the name of the functions different, e.g.

                Code:
                DECLARE FUNCTION MyGetCursorPos LIB "USER32.DLL" ALIAS "GetCursorPos" (BYVAL lpPoint AS POINT PTR) AS LONG
                
                DECLARE FUNCTION GetCursorPos LIB "USER32.DLL" ALIAS "GetCursorPos" (lpPoint AS POINT) AS LONG
                In general, the good translators choose the syntax that allows easier use of the function.

                For example, the function SetWindowText is declared in C++ as:

                Code:
                BOOL SetWindowText(      
                    HWND hWnd,
                    LPCTSTR lpString
                );
                and MSDN says that lpString is a pointer to a null-terminated string to be used as the new title or control text.

                If you take it literally and declare it as:

                Code:
                DECLARE FUNCTION SetWindowText LIB "USER32.DLL" ALIAS "SetWindowTextA" ( _
                   BYVAL hWnd AS DWORD _                                ' __in HWND hWnd
                 , BYVAL lpString AS ASCIIZ PTR _                       ' __in_opt LPCSTR lpString
                 ) AS LONG                                              ' BOOL
                you will have to use it as follows:

                Code:
                DIM lpString AS ASCIIZ * 256
                lpString = "Some text"
                SetWindowText hWnd, VARPTR(lpString)
                or as follows:

                Code:
                DIM lpString AS STRING
                lpString = "Some text"
                SetWindowText hWnd, STRPTR(lpString)
                but if you declare it as:

                Code:
                DECLARE FUNCTION SetWindowText LIB "USER32.DLL" ALIAS "SetWindowTextA" ( _
                   BYVAL hWnd AS DWORD _                                ' __in HWND hWnd
                 , BYREF lpString AS ASCIIZ _                           ' __in_opt LPCSTR lpString
                 ) AS LONG                                              ' BOOL
                you can use it as:

                Code:
                DIM lpString AS ASCIIZ * 256
                lpString = "Some text"
                SetWindowText hWnd, lpString
                or even as:

                Code:
                SetWindowText hWnd, "Some text"
                José Roca
                Member
                Last edited by José Roca; 14 Jul 2009, 04:05 PM.
                Forum: http://www.jose.it-berater.org/smfforum/index.php

                Comment


                • #9
                  For reasons unknown, I had always assumed there was a "single" declaration to an API - as defined by Microsoft
                  This whine's time has come

                  About the middle there is a section on "WIN API Declarations"
                  Michael Mattias
                  Tal Systems (retired)
                  Port Washington WI USA
                  [email protected]
                  http://www.talsystems.com

                  Comment


                  • #10
                    Thanks guys. As I've said before, sometimes I read things early on, but until I actually use them they don't sink in.

                    Whine? I've been known to do that.

                    Does anyone remember the "pipette" in Chemistry 101? You can blow as hard on one end as you want, but the hole is so small that the amount of air you can generate out of the other end is somewhat small.

                    PowerBASIC, the Windows/SDK part anyways, is like that. Since day one I've wanted to learn by "drinking from a fire hose" but mostly I get the draft from the "pipette".

                    Tastes great, always leaves me wanting more!

                    Joke Time:

                    What did the snail say when riding on the back of a turtle?

                    "Wheeeeeeeeeeeeee!"

                    Comment

                    Working...
                    X