Announcement

Collapse
No announcement yet.

Pascal calling convention...

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

  • Pascal calling convention...

    I need help with this C-code
    It is a callback function from a OEM-DLL
    Code:
      BOOL PASCAL StatusCallback{LPSTR szItem,
                                 long Percent,
                                 long Status,
                                 void *lpUserData}
    
    I interpret this as follows:
      
    Function StatusCallback BDECL(szItem as Asciiz,
                                  Byval Percent as Long,
                                  Byval Status as Long,
                                  Byval lpUserData as DWord)as long
      
    But that is obviosly wrong. Omitting BDECL and all works like a charm
    This is from PB/DLL help-file
     
    BDECL Specifies that the declared procedure uses the Basic/Pascal calling convention. When a procedure calls a BDECL procedure, it passes its parameters on the stack left to right. It is the responsibility of the called procedure to clean up the stack before returning to the calling procedure.
    How do I clean the stack?


    ------------------
    Fred
    mailto:[email protected][email protected]</A>
    http://www.oxenby.se

    Fred
    mailto:[email protected][email protected]</A>
    http://www.oxenby.se

  • #2
    I assume that you are calling a PowerBASIC DLL _from_ C? In that case, the C compiler used to compile the _calling_ code should automatically clean up the stack. If it does not automatically do this, you'll need to pop the parameters from the stack on return to set the stack frame pointer back to the initial position.

    When you say "it is obviously wrong", can you explain that a little more clearly please? Does it cause a GPF, and if so, at what point? If the calling code is not cleaning up the stack, then I would assume that the GPF occurs on or after execution returns to the calling code from the DLL.



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

    Comment


    • #3
      Fred,

      I have a sneaking suspicion that Microsoft have redefined PASCAL
      calling convention. In 16 bit, it was pushed from left to right
      but I think they have done something that is more like STDCALL.

      If you have omitted the BDECL, I think it means its STDCALL but
      to test what you are after, I would try it as CDECL and SDECL as
      well.

      It can only crash if its wrong.

      Regards,

      [email protected]

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

      www.masm32.com

      Comment


      • #4
        Fred, the description for BDECL in the doc's is in need of correction. The BDECL description should state:
        BDECL Specifies that the declared procedure uses the Basic/Pascal calling convention. When a procedure calls a BDECL procedure, it passes its parameters on the stack from left to right. It is the responsibility of the _called_ procedure to clean up the stack before returning to the calling procedure.
        Therefore, the exported PB function that uses BDECL should automatically clean up the stack for you. I've emailed R&D to confirm this aspect of the compiler.

        For the lurkers: By default, PowerBASIC uses SDECL/STDCALL which (like CDECL) passes parameters from right to left and the stack is cleaned up by the called code.

        CDECL also passes from right to left, but the stack cleanup is the responsibility of the _calling_ code.



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

        Comment


        • #5
          Confirmed by R&D.

          BDECL functions _IN_ PowerBASIC code automatically clean up the stack (as I expected).


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

          Comment


          • #6
            Fred,

            The PASCAL is now mapped in C/C++ as follows from the
            msdev help file:

            The __pascal, __fortran, and __syscall calling conventions are no
            longer supported. You can emulate their functionality by using one
            of the supported calling conventions and appropriate linker options.

            WINDOWS.H now supports the WINAPI macro, which translates to the
            appropriate calling convention for the target. Use WINAPI where
            you previously used PASCAL or __far __pascal.

            I haven't checked the WINAPI signature but I think it's
            stdcall convention. Hope this helps.

            Cheers,
            Cecil

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

            Comment


            • #7
              Thank you all.
              I am calling a C-DLL from Powerbasic.
              When using 'BDECL' my variables did not carry the information I was expected
              (lpUserData=>ptr to a UDT,sZItem=>ptr to a string)
              After 5 or 6 calls to this StatusCallback I get a GPF when exiting the callback
              Function = 0 was pointed out as the cod beeing executed
              ----
              Using 'SDECL' (or nothing) the StatusCallback-function worked ok.
              ----
              I suspected that the author of this DLL has made a 'typo' in their dokumentation,
              so I checked other products of their, but the same declaration appeard there too.
              That is: 'FAR PASCAL'
              ----
              I was consulting the PB/DLL documentation and was surprised that _myself_ and not
              _the compiler_ was supposed to add code for 'cleaning the stack'
              I had no idea at all on 'cleaning the stack'



              ------------------
              Fred
              mailto:[email protected][email protected]</A>
              http://www.oxenby.se

              Fred
              mailto:[email protected][email protected]</A>
              http://www.oxenby.se

              Comment


              • #8
                FAR PASCAL isn't an error, as such, it just doesn't mean what you thought it
                did. The 16-bit Windows API calls do use the far Pascal calling convention.
                The 32-bit Windows API calls use an approach that Microsoft quite unsubtly
                markets as the "standard" calling convention.

                The fact that FAR PASCAL is in uppercase is a hint to you that they are
                actually equates. So, it is possible to redefine them, making it easier to
                port the C program to other operating environments. It appears that the
                original C program, here, was written for 16-bit Windows: FAR translated
                into something like _far and PASCAL translated into _pascal perhaps.
                Under 32-bit Windows, FAR would be translated away into nothing, and
                PASCAL would become... have you guessed? __stdcall of course!
                These equates are actually part of the Windows include files, so the transition
                was transparent to the C programmer, and only comes back to haunt us now.

                The long and short of it is, you should treat FAR PASCAL in a 32-bit
                program as being just an ordinary declaration. If you want to put an explicit
                calling convention on your declare, use SDECL or STDCALL, but these are the
                normal default in any event.

                I was consulting the PB/DLL documentation and was surprised that _myself_
                and not _the compiler_ was supposed to add code for 'cleaning the stack'
                I've asked for the documentation to be revised, as I think it would be easy to
                draw that conclusion. The compiler will always take care of cleaning up the
                stack. The description in the docs has to do with whether the compiler needs
                to clean up the stack as part of exiting the function, or whether the compiler
                has to clean up the stack after the function has exited and returned. This is
                not a detail that most people will ever need to consider.

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

                Comment

                Working...
                X