Loading ...
Sorry, an error occurred while loading the content.

RE: [libertybasic] Re: Passing / Receiving large (64bit) parameters in API Calls

Expand Messages
  • Brandon Parker
    Mike, Have you tried changing this: calldll #CAN, xlGetChannelMask ,_ hwType as short,_ hwIndex as short,_ hwChannel as short,_ ChannelMask as struct to
    Message 1 of 9 , Jan 21, 2013
    • 0 Attachment
      Mike, Have you tried changing this: calldll #CAN, "xlGetChannelMask",_
      hwType as short,_
      hwIndex as short,_
      hwChannel as short,_
      ChannelMask as struct to this: calldll #CAN, "xlGetChannelMask",_
      hwType as long,_
      hwIndex as long,_
      hwChannel as long,_
      ChannelMask as ulong Taking a quick look at the documentation I would use long as the types for (hwType, hwIndex, hwChannel) and ulong for ChannelMask. Using ulong vs. struct will not make any difference in how LB handles the return value, but I vaguely remember having issues when trying to use the return value as a struct. {:0) Brandon

      To: libertybasic@yahoogroups.com
      From: mike.collins1@...
      Date: Mon, 21 Jan 2013 16:52:33 +0000
      Subject: [libertybasic] Re: Passing / Receiving large (64bit) parameters in API Calls


























      Hi Stefan,



      I think I understand your example, at least in terms of passing pointers to the structures. I didn't really understand the "GetProcAddress" part and what the different values for "pGetDiskFreeSpaceEx" meant (don't think it matters for the purpose of our discussion).



      I still have a problem receiving a 64bit number as the returned value. When I try the following code, Liberty disappears with no error messages:



      struct ChannelMask,_

      ChannelMaskLow as ulong,_

      ChannelMaskHigh as ulong



      calldll #CAN, "xlGetChannelMask",_

      hwType as short,_

      hwIndex as short,_

      hwChannel as short,_

      ChannelMask as struct



      print "xlGetChannelMask = "; ChannelMask.ChannelMaskLow.struct + ChannelMask.ChannelMaskLow.struct * hexdec("&H100000000")



      Obviously there was some prior code to open the DLL etc. and I have called some other simple functions of this DLL which return with a good status.



      It behaves OK if I make ChannelMask a Long but presumably I'm not then getting the full return value ?



      Mike



      --- In libertybasic@yahoogroups.com, Stefan Pendl wrote:

      >

      > Am 18.01.2013 10:35, schrieb mike_collins_23:

      > > Hi, I would like to use Liberty Basic to access a Vector Informatik dll (vxlapi.dll). Some of the calls require the transfer (or return) of a 64bit value (this is actually a bit mask). If parameters are passed on a stack to Windows API's then possibly 2 LONG parameters would look like a 64 bit value. The problem would still be how to handle the returned 64bit value ?

      > > Any information would be appreciated.

      > > Mike

      > >

      >

      > See the code below, which is used to get the free space of a drive.

      > GetDiskFreeSpaceEx uses a LONG_INTEGER type, which is 64-bit.

      >

      >

      > '---code start (watch for line wraps)

      >

      > i = 1

      > while word$(Drives$, i) <> ""

      > drive$ = word$(Drives$, i)

      > print drive$; " ... "; GetDiskFreeSpace(drive$); " Bytes free"

      > i=i+1

      > wend

      > end

      >

      > function GetDiskFreeSpace(driveLetter$)

      > calldll #kernel32, "GetModuleHandleA" , _

      > "kernel32.dll" as ptr, _

      > hKernel as ulong

      >

      > calldll #kernel32, "GetProcAddress" , _

      > hKernel as ulong, _

      > "GetDiskFreeSpaceExA" as ptr, _

      > pGetDiskFreeSpaceEx as ulong

      >

      > if pGetDiskFreeSpaceEx = 0 then

      > struct lpSectorsPerCluster, value as ulong

      > struct lpBytesPerSector, value as ulong

      > struct lpNumberOfFreeClusters, value as ulong

      > struct lpTotalNumberOfClusters, value as ulong

      >

      > calldll #kernel32, "GetDiskFreeSpaceA" , _

      > driveLetter$ as ptr, _

      > lpSectorsPerCluster as struct, _

      > lpBytesPerSector as struct, _

      > lpNumberOfFreeClusters as struct, _

      > lpTotalNumberOfClusters as struct, _

      > infoOK as ulong

      >

      > GetDiskFreeSpace = lpBytesPerSector.value.struct *

      > lpSectorsPerCluster.value.struct * _

      > lpNumberOfFreeClusters.value.struct

      > else

      > struct lpFreeBytesAvailableToCaller, LowByte as ulong, HighByte

      > as ulong

      > struct lpTotalNumberOfBytes, LowByte as ulong, HighByte as ulong

      > struct lpTotalNumberOfFreeBytes, LowByte as ulong, HighByte as

      > ulong

      >

      > calldll #kernel32, "GetDiskFreeSpaceExA" , _

      > driveLetter$ as ptr, _

      > lpFreeBytesAvailableToCaller as struct, _

      > lpTotalNumberOfBytes as struct, _

      > lpTotalNumberOfFreeBytes as struct, _

      > infoOK as ulong

      >

      > GetDiskFreeSpace = lpTotalNumberOfFreeBytes.HighByte.struct *

      > HexDec("100000000") + _

      > lpTotalNumberOfFreeBytes.LowByte.struct

      > end if

      > end function

      >

      > '---code end

      >

      > --

      > Stefan Pendl

      > http://stefanpendl.runbasichosting.com/

      >

      > LB 4.04 Pro ... http://www.libertybasic.com/assist.html

      > LB 4.04 ....... http://www.libertybasic.com/lb404setup.exe

      >

      > LB Community Wiki .............. http://basic.wikispaces.com/

      > LB Programmer's Encyclopedia ... http://lbpe.wikispaces.com/

      > LB Bug Tracker ................. http://libertybasicbugs.wikispaces.com/

      >

      > Books at http://www.lulu.com/ and http://www.amazon.com/

      > Alyce Watson ... APIs for Liberty BASIC

      > Carl Gundel .... Beginning Programming with Liberty BASIC

      >

      > Windows 7 Home Premium 64-bit SP1

      > AMD Turion X2 RM-70 2GHz, 4GB RAM

      >


















      [Non-text portions of this message have been removed]
    • Stefan Pendl
      ... A structure is not a valid return type for LB. We would need to know how the C declaration of the API function looks like to make the correct decision. Is
      Message 2 of 9 , Jan 21, 2013
      • 0 Attachment
        Am 21.01.2013 17:52, schrieb mike_collins_23:
        > Hi Stefan,
        >
        > I think I understand your example, at least in terms of passing pointers to the structures. I didn't really understand the "GetProcAddress" part and what the different values for "pGetDiskFreeSpaceEx" meant (don't think it matters for the purpose of our discussion).
        >
        > I still have a problem receiving a 64bit number as the returned value. When I try the following code, Liberty disappears with no error messages:
        >
        > struct ChannelMask,_
        > ChannelMaskLow as ulong,_
        > ChannelMaskHigh as ulong
        >
        > calldll #CAN, "xlGetChannelMask",_
        > hwType as short,_
        > hwIndex as short,_
        > hwChannel as short,_
        > ChannelMask as struct
        >
        > print "xlGetChannelMask = "; ChannelMask.ChannelMaskLow.struct + ChannelMask.ChannelMaskLow.struct * hexdec("&H100000000")
        >
        > Obviously there was some prior code to open the DLL etc. and I have called some other simple functions of this DLL which return with a good status.
        >
        > It behaves OK if I make ChannelMask a Long but presumably I'm not then getting the full return value ?
        >
        > Mike
        >

        A structure is not a valid return type for LB.

        We would need to know how the C declaration of the API function looks
        like to make the correct decision.

        Is there a place on the net where one can download the C header file?


        --
        Stefan Pendl
        http://stefanpendl.runbasichosting.com/

        LB 4.04 Pro ... http://www.libertybasic.com/assist.html
        LB 4.04 ....... http://www.libertybasic.com/lb404setup.exe

        LB Community Wiki .............. http://basic.wikispaces.com/
        LB Programmer's Encyclopedia ... http://lbpe.wikispaces.com/
        LB Bug Tracker ................. http://libertybasicbugs.wikispaces.com/

        Books at http://www.lulu.com/ and http://www.amazon.com/
        Alyce Watson ... APIs for Liberty BASIC
        Carl Gundel .... Beginning Programming with Liberty BASIC

        Windows 7 Home Premium 64-bit SP1
        AMD Turion X2 RM-70 2GHz, 4GB RAM
      • mike_collins_23
        Hi Stefan, You can download the complete package at:
        Message 3 of 9 , Jan 22, 2013
        • 0 Attachment
          Hi Stefan,

          You can download the complete package at:

          https://www.vector.com/vi_downloadcenter_en.html?product=xllib&formular_treffer_submit=1&sprachumschaltung=1

          and select XL Driver Library 8.3 (it's just over 18MB).

          The relevant part of vxlapi.h is:

          //////////////////////////////////////////////////////////////////////
          // For the timestamps and the access mask the API use 64 bit values
          typedef unsigned __int64 XLuint64;

          //////////////////////////////////////////////////////////////////////
          typedef char *XLstringType;

          //////////////////////////////////////////////////////////////////////
          // accessmask
          typedef XLuint64 XLaccess;

          //////////////////////////////////////////////////////////////////////

          and of the Driver Manual:

          3.1.8 xlGetChannelMask
          Syntax XLaccess xlGetChannelMask (
          int hwType,
          int hwIndex,
          int hwChannel);
          Description Retrieves the channel mask of a particular hardware channel.
          Input Parameters „­ hwType
          Required to distinguish the different hardware types, e.g.
          - -1
          - XL_HWTYPE_CANCARDXL
          - XL_HWTYPE_CANBOARDXL
          - ¡K
          Parameter -1 can be used if the hardware type does not matter.
          „­ hwIndex
          Required to distinguish between two or more devices of the same hardware
          type (-1, 0, 1¡K). Parameter -1 is used to retrieve the first available hardware.
          The type depends on hwType.
          „­ hwChannel
          Required to distinguish the hardware channel of the selected device (-1, 0, 1, ¡K).
          Parameter -1 can be used to retrieve the first available channel.
          Return Value Returns the channel mask.

          Mike

          --- In libertybasic@yahoogroups.com, Stefan Pendl wrote:
          >
          > Am 21.01.2013 17:52, schrieb mike_collins_23:
          > > Hi Stefan,
          > >
          > > I think I understand your example, at least in terms of passing pointers to the structures. I didn't really understand the "GetProcAddress" part and what the different values for "pGetDiskFreeSpaceEx" meant (don't think it matters for the purpose of our discussion).
          > >
          > > I still have a problem receiving a 64bit number as the returned value. When I try the following code, Liberty disappears with no error messages:
          > >
          > > struct ChannelMask,_
          > > ChannelMaskLow as ulong,_
          > > ChannelMaskHigh as ulong
          > >
          > > calldll #CAN, "xlGetChannelMask",_
          > > hwType as short,_
          > > hwIndex as short,_
          > > hwChannel as short,_
          > > ChannelMask as struct
          > >
          > > print "xlGetChannelMask = "; ChannelMask.ChannelMaskLow.struct + ChannelMask.ChannelMaskLow.struct * hexdec("&H100000000")
          > >
          > > Obviously there was some prior code to open the DLL etc. and I have called some other simple functions of this DLL which return with a good status.
          > >
          > > It behaves OK if I make ChannelMask a Long but presumably I'm not then getting the full return value ?
          > >
          > > Mike
          > >
          >
          > A structure is not a valid return type for LB.
          >
          > We would need to know how the C declaration of the API function looks
          > like to make the correct decision.
          >
          > Is there a place on the net where one can download the C header file?
          >
          >
          > --
          > Stefan Pendl
          > http://stefanpendl.runbasichosting.com/
          >
          > LB 4.04 Pro ... http://www.libertybasic.com/assist.html
          > LB 4.04 ....... http://www.libertybasic.com/lb404setup.exe
          >
          > LB Community Wiki .............. http://basic.wikispaces.com/
          > LB Programmer's Encyclopedia ... http://lbpe.wikispaces.com/
          > LB Bug Tracker ................. http://libertybasicbugs.wikispaces.com/
          >
          > Books at http://www.lulu.com/ and http://www.amazon.com/
          > Alyce Watson ... APIs for Liberty BASIC
          > Carl Gundel .... Beginning Programming with Liberty BASIC
          >
          > Windows 7 Home Premium 64-bit SP1
          > AMD Turion X2 RM-70 2GHz, 4GB RAM
          >
        • Stefan Pendl
          ... Could you try the following? ---code start (watch for line wraps) calldll #vxlapi, xlGetChannelMask , _ hwType as long, _ hwIndex as long, _
          Message 4 of 9 , Jan 22, 2013
          • 0 Attachment
            Am 22.01.2013 10:07, schrieb mike_collins_23:
            >
            > The relevant part of vxlapi.h is:
            >
            > //////////////////////////////////////////////////////////////////////
            > // For the timestamps and the access mask the API use 64 bit values
            > typedef unsigned __int64 XLuint64;
            >
            > //////////////////////////////////////////////////////////////////////
            > typedef char *XLstringType;
            >
            > //////////////////////////////////////////////////////////////////////
            > // accessmask
            > typedef XLuint64 XLaccess;
            >
            > //////////////////////////////////////////////////////////////////////
            >
            > and of the Driver Manual:
            >
            > 3.1.8 xlGetChannelMask
            > Syntax XLaccess xlGetChannelMask (
            > int hwType,
            > int hwIndex,
            > int hwChannel);
            > Description Retrieves the channel mask of a particular hardware channel.
            > Input Parameters „­ hwType
            > Required to distinguish the different hardware types, e.g.
            > - -1
            > - XL_HWTYPE_CANCARDXL
            > - XL_HWTYPE_CANBOARDXL
            > - ¡K
            > Parameter -1 can be used if the hardware type does not matter.
            > „­ hwIndex
            > Required to distinguish between two or more devices of the same hardware
            > type (-1, 0, 1¡K). Parameter -1 is used to retrieve the first available hardware.
            > The type depends on hwType.
            > „­ hwChannel
            > Required to distinguish the hardware channel of the selected device (-1, 0, 1, ¡K).
            > Parameter -1 can be used to retrieve the first available channel.
            > Return Value Returns the channel mask.
            >
            > Mike
            >

            Could you try the following?

            '---code start (watch for line wraps)

            calldll #vxlapi, "xlGetChannelMask", _
            hwType as long, _
            hwIndex as long, _
            hwChannel as long, _
            accessmask as double

            '---code end

            If that works, then we could try to convert the double value similar to
            the VarR4FromR8 example at
            http://www.b6sw.com/forum/content.php?mode=hints&t=223 , but using
            VarUI8FromR8 at
            http://msdn.microsoft.com/en-us/library/windows/desktop/ms644397%28v=vs.85%29.aspx


            --
            Stefan Pendl
            http://stefanpendl.runbasichosting.com/

            LB 4.04 Pro ... http://www.libertybasic.com/assist.html
            LB 4.04 ....... http://www.libertybasic.com/lb404setup.exe

            LB Community Wiki .............. http://basic.wikispaces.com/
            LB Programmer's Encyclopedia ... http://lbpe.wikispaces.com/
            LB Bug Tracker ................. http://libertybasicbugs.wikispaces.com/

            Books at http://www.lulu.com/ and http://www.amazon.com/
            Alyce Watson ... APIs for Liberty BASIC
            Carl Gundel .... Beginning Programming with Liberty BASIC

            Windows 7 Home Premium 64-bit SP1
            AMD Turion X2 RM-70 2GHz, 4GB RAM
          • mike_collins_23
            Hi Stefan, I m not sure why you wanted me to use Long s to pass the parameters as I believe they should be short. Anyway, whichever I use, if I use a Double
            Message 5 of 9 , Jan 22, 2013
            • 0 Attachment
              Hi Stefan,

              I'm not sure why you wanted me to use Long's to pass the parameters as I believe they should be short. Anyway, whichever I use, if I use a Double for the returned value, Liberty crashes with "Virtual Machine Stack Overflow". If I use a Long for the returned value it doesn't crash.

              Unfortunately I don't think I have got far enough with the program to get a meaningful value returned (when I use a Long it's value is zero).
              I don't want to take up too much of your time so if you think this is too tricky for Liberty I will abandon the idea.

              Mike

              --- In libertybasic@yahoogroups.com, Stefan Pendl wrote:
              >
              > Am 22.01.2013 10:07, schrieb mike_collins_23:
              > >
              > > The relevant part of vxlapi.h is:
              > >
              > > //////////////////////////////////////////////////////////////////////
              > > // For the timestamps and the access mask the API use 64 bit values
              > > typedef unsigned __int64 XLuint64;
              > >
              > > //////////////////////////////////////////////////////////////////////
              > > typedef char *XLstringType;
              > >
              > > //////////////////////////////////////////////////////////////////////
              > > // accessmask
              > > typedef XLuint64 XLaccess;
              > >
              > > //////////////////////////////////////////////////////////////////////
              > >
              > > and of the Driver Manual:
              > >
              > > 3.1.8 xlGetChannelMask
              > > Syntax XLaccess xlGetChannelMask (
              > > int hwType,
              > > int hwIndex,
              > > int hwChannel);
              > > Description Retrieves the channel mask of a particular hardware channel.
              > > Input Parameters „­ hwType
              > > Required to distinguish the different hardware types, e.g.
              > > - -1
              > > - XL_HWTYPE_CANCARDXL
              > > - XL_HWTYPE_CANBOARDXL
              > > - ¡K
              > > Parameter -1 can be used if the hardware type does not matter.
              > > „­ hwIndex
              > > Required to distinguish between two or more devices of the same hardware
              > > type (-1, 0, 1¡K). Parameter -1 is used to retrieve the first available hardware.
              > > The type depends on hwType.
              > > „­ hwChannel
              > > Required to distinguish the hardware channel of the selected device (-1, 0, 1, ¡K).
              > > Parameter -1 can be used to retrieve the first available channel.
              > > Return Value Returns the channel mask.
              > >
              > > Mike
              > >
              >
              > Could you try the following?
              >
              > '---code start (watch for line wraps)
              >
              > calldll #vxlapi, "xlGetChannelMask", _
              > hwType as long, _
              > hwIndex as long, _
              > hwChannel as long, _
              > accessmask as double
              >
              > '---code end
              >
              > If that works, then we could try to convert the double value similar to
              > the VarR4FromR8 example at
              > http://www.b6sw.com/forum/content.php?mode=hints&t=223 , but using
              > VarUI8FromR8 at
              > http://msdn.microsoft.com/en-us/library/windows/desktop/ms644397%28v=vs.85%29.aspx
              >
              >
              > --
              > Stefan Pendl
              > http://stefanpendl.runbasichosting.com/
              >
              > LB 4.04 Pro ... http://www.libertybasic.com/assist.html
              > LB 4.04 ....... http://www.libertybasic.com/lb404setup.exe
              >
              > LB Community Wiki .............. http://basic.wikispaces.com/
              > LB Programmer's Encyclopedia ... http://lbpe.wikispaces.com/
              > LB Bug Tracker ................. http://libertybasicbugs.wikispaces.com/
              >
              > Books at http://www.lulu.com/ and http://www.amazon.com/
              > Alyce Watson ... APIs for Liberty BASIC
              > Carl Gundel .... Beginning Programming with Liberty BASIC
              >
              > Windows 7 Home Premium 64-bit SP1
              > AMD Turion X2 RM-70 2GHz, 4GB RAM
              >
            • Stefan Pendl
              ... int is the integer data type, which must be translated as long for LB, see http://www.b6sw.com/forum/content.php?mode=hints&t=235 short would be used for
              Message 6 of 9 , Jan 22, 2013
              • 0 Attachment
                Am 22.01.2013 13:06, schrieb mike_collins_23:
                > Hi Stefan,
                >
                > I'm not sure why you wanted me to use Long's to pass the parameters as I believe they should be short. Anyway, whichever I use, if I use a Double for the returned value, Liberty crashes with "Virtual Machine Stack Overflow". If I use a Long for the returned value it doesn't crash.
                >
                > Unfortunately I don't think I have got far enough with the program to get a meaningful value returned (when I use a Long it's value is zero).
                > I don't want to take up too much of your time so if you think this is too tricky for Liberty I will abandon the idea.
                >

                int is the integer data type, which must be translated as long for LB,
                see http://www.b6sw.com/forum/content.php?mode=hints&t=235
                short would be used for short or word types.

                It seems there is no way around a wrapper DLL, that allows LB to handle
                64-bit integers.

                LB would call a different DLL that in turn calls the function returning
                the 64-bit integer. The returned 64-bit integer will be converted into
                something LB can handle, like a LARGE_INTEGER structure.


                --
                Stefan Pendl
                http://stefanpendl.runbasichosting.com/

                LB 4.04 Pro ... http://www.libertybasic.com/assist.html
                LB 4.04 ....... http://www.libertybasic.com/lb404setup.exe

                LB Community Wiki .............. http://basic.wikispaces.com/
                LB Programmer's Encyclopedia ... http://lbpe.wikispaces.com/
                LB Bug Tracker ................. http://libertybasicbugs.wikispaces.com/

                Books at http://www.lulu.com/ and http://www.amazon.com/
                Alyce Watson ... APIs for Liberty BASIC
                Carl Gundel .... Beginning Programming with Liberty BASIC

                Windows 7 Home Premium 64-bit SP1
                AMD Turion X2 RM-70 2GHz, 4GB RAM
              Your message has been successfully submitted and would be delivered to recipients shortly.