Announcement

Collapse
No announcement yet.

Byval/ByRef in DECLAREs

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

  • Byval/ByRef in DECLAREs

    When declaring functions in external DLLs (in this case the Win API) using the DECLARE statement, is it required that
    I spell out the parameter passing function or can I leave the parameter list 'generic' and use BYVAL/BYREF when I
    actually call the function? IOW, can my declare be:

    Declare SomeSub Lib "External.Dll" (Param1 as DWord, Param2 as Long, Param3 as SomeUDT)

    and then in code:

    SomeSub BYVAL Param1, BYREF Param2, BYREF Param3 ' UDTs can only be passed BYREF

    Granted, it's cleaner syntax to define the passing method in the DECLARE, but when debugging it's easier to just change
    the actual call.

    Sorry if this is covered in the docs, but I spent the afternoon trying to get a <expletive deleted> WinAPI function to
    work right, without much success. It's still bugging me, so I thought I'd post from home in the hope that
    I'll forget about it and not have any API nightmares.

    Thanks!



    ------------------
    Mark Newman
    Mark Newman

  • #2
    If you declare all parameters as BYREF (the default), then the compiled code will be constructed to expect to receive pointers to the actual data. Likewise, if you specify BYVAL, the actual values will be expected, not pointers to the values.

    When you pass parameters from the calling code with an *explicit* BYVAL, you effectively switch off type-checking by the compiler for that parameter.

    Now, if the called code expects a pointer (say, to a LONG), and you pass a BYVAL LONG from the calling code, the called code will receive an absolute LONG value, not an address of a LONG value. This will almost certainly earn you a GPF when the absolute LONG value tries to be used as a pointer address to a LONG.

    Essentially, declarations and sub/function prototypes are an important part of any program - they tell the compiler what sort of parameters the sub/function is going to be passed and how they should be passed. If you specify the wrong passing methods, you'll have to handle all of the type checking yourself (and get it right), which may add significant overhead to your development time.

    Therefore, if the compiler offers parameter type-checking, why not use it?

    May I suggest that you review the documentation that discusses BYVAL, BYREF and BYCOPY parameter passing - once you understand those methods, you'll understand how you can handle parameter passing.

    I hope this helps!


    ------------------
    Lance
    PowerBASIC Support
    mailto:[email protected][email protected]</A>
    Lance
    mailto:[email protected]

    Comment


    • #3
      Thanks Lance!

      I don't have PB installed at home so I can't look over the docs.
      I'm just trying to 'get my mind straight' and develop a plan of
      attack for Monday morning. Here it is Saturday afternoon & I'm
      still bugged by the problem, which violates my 'leave work at work'
      policy.

      First thing I'll check is my declares of the WinAPI functions to
      make sure I've got them right. They're mostly DWORDs and UDTs, but
      in some functions they're passed BYVAL, in others the function wants
      a pointer to them. I suspect I've got a few mixups.


      ------------------
      Mark Newman
      Mark Newman

      Comment


      • #4
        Mark, since many API function declarations exist in the WIN32API.INC and related .INC files, it makes sense to use those rather than rewrite them from scratch.

        I often see folks move code from VB to PB and then battle against the VB declarations. The VB declarations often need some translation due to the way VB handles passing strings BYVAL to DLL's, etc.

        In these cases, I usually suggest that the entire VB declaration section be dropped, and replaced with one line of code:
        Code:
        #INCLUDE "WIN32API.INC"
        I hope this helps!

        ------------------
        Lance
        PowerBASIC Support
        mailto:[email protected][email protected]</A>
        Lance
        mailto:[email protected]

        Comment


        • #5
          When you pass parameters from the calling code with an *explicit* BYVAL, you effectively switch off type-checking by the compiler for that parameter.
          That statement, exactly as written, should be in the documentation for the CALL verb. (and maybe in that for FUNCTION and SUB as well).

          MCM


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

          Comment


          • #6
            Lance,

            Oooh, how I wish that WIN32API.INC had these declares! I'm using functions in the SETUPAPI.DLL
            and HID.DLL (HID refers to "Human Interface Device", which could be a keyboard, mouse, joystick,
            gamepad, etc.) libraries to interface with some USB devices. The SETUPAPI.DLL functions are
            documented quite well in MSDN, but there's only the slightest mention of HID and no function
            documentation. I do have a Windows driver book that covers HID some, so I know what the functions
            are doing, but of course all the source is in C.

            It's especially frustrating since I've had a good amount of success with PB of late, recently
            completing a suite of 8 engineering test programs that helped us test & ship a new product on
            a very tight schedule. I actually enjoyed distributing the apps via email: "Just copy the attached
            exe and run it". No VB runtimes, no DLL Heck!

            But these dang C-porting projects are going to have me pushing up daisies before too long!

            Thanks!


            ------------------
            Mark Newman
            Mark Newman

            Comment

            Working...
            X