64 bit pointers?

Tags: #<Tag:0x00007f6883def998>

I feel like I should know this, but having been out of the CW game for a decade and still using C6 I’m more than a little behind the curve :slightly_smiling_face:

What’s this decades workaround for being able to handle 64 bit values as pointers being received from external sources? Is it still a group with 2 LONGs in it? Or did someone figure out something better when I wasn’t paying attention?

And on a tangent, I assume that we’re still waiting on SV to implement native 64 bit support?

While there are 44 exported procedures in the 11.13505 RTL that start with Cla$i64
I’m not aware of a way to declare 64 bit variables yet.

The clarionhelp.chm mentions INT64 and UINT64 as coming in a future release

So yup, use a group.
FWIW %cwroot%\libsrc\win\svapi.inc has _ULARGE_INTEGER
however the group seems more appropriate for a LARGE not a ULARGE
as both HiPart and LowPart are LONG

here’s something I wrote for Diego during a CIDC presentation 3 years ago.
Looks like I did the same thing with Hi not being a ULONG

  PROGRAM

INCLUDE('svapi.inc'),ONCE ! for _ULarge_Integer

INCLUDE('Windows.inc'),ONCE ! for DWORD
!https://msdn.microsoft.com/en-us/library/windows/desktop/aa383742(v=vs.85).aspx
ULarge GROUP,TYPE
Lo      DWORD
Hi      DWORD
       END 


ToHex:Lower EQUATE(TRUE)
ToHex:Upper EQUATE(FALSE)

    MAP
      INCLUDE('CWUTIL.INC'),ONCE
      ToHex(CONST *_ULARGE_INTEGER Value, BOOL LowerCase=ToHex:Upper),STRING
      ToHex(CONST *ULARGE          Value, BOOL LowerCase=ToHex:Upper),STRING
!ToHex PROCEDURE(CONST *FILETIME Value),STRING
      ODS(STRING Msg)         
       MODULE('API')
          OutputDebugString(*CSTRING MSG),PASCAL,RAW,NAME('OutputDebugStringA')
       END
    END


MyLarge  LIKE(_ULARGE_INTEGER)
MyULarge LIKE(ULARGE)
  CODE
  DO Test_MyLarge
?                               ods('-{42}')
  DO Test_MyULarge
?                               ods('-- done --')

Test_MyLarge ROUTINE 
  MyLarge.HighPart = 64000
  MyLarge.LowPart  = 32000
?                               ods('MyLarge['& ToHex(MyLarge) &']')

  MyLarge.HighPart = 65535
  MyLarge.LowPart  = 32767
?                               ods('MyLarge['& ToHex(MyLarge) &']')

  CLEAR(MyLarge.HighPart,1)
  CLEAR(MyLarge.LowPart ,1)
?                               ods('MyLarge['& ToHex(MyLarge) &']')

  CLEAR(MyLarge.HighPart,-1)
  CLEAR(MyLarge.LowPart ,-1)
?                               ods('MyLarge['& ToHex(MyLarge) &']')


Test_MyULarge ROUTINE 
  MyULarge.Hi = 64000
  MyULarge.Lo = 32000
?                               ods('MyULarge['& ToHex(MyULarge) &']')
?                               ods('MyULarge['& ToHex(MyULarge, ToHex:Lower) &'] --- LOWER')

  MyULarge.Hi = 65535
  MyULarge.Lo = 32767
?                               ods('MyULarge['& ToHex(MyULarge) &']')

  CLEAR(MyULarge.Hi,1)
  CLEAR(MyULarge.Lo,1)
?                               ods('MyULarge['& ToHex(MyULarge) &']')

  CLEAR(MyULarge.Hi,-1)
  CLEAR(MyULarge.Lo,-1)
?                               ods('MyULarge['& ToHex(MyULarge) &']')



ToHex PROCEDURE(CONST *ULARGE Value, BOOL LowerCase=FALSE)!,STRING
   CODE
?                               ods('Value Hi['& Value.Hi &'] Low['& Value.Lo &']')
   RETURN LongToHex(Value.Hi, LowerCase) & LongToHex(Value.Lo, LowerCase)

ToHex PROCEDURE(CONST *_ULARGE_INTEGER Value, BOOL LowerCase=FALSE)!,STRING
   CODE 
?                               ods('Value Hi['& Value.HighPart &'] Low['& Value.LowPart &']')
   RETURN LongToHex(Value.HighPart, LowerCase) & LongToHex(Value.LowPart, LowerCase)


!ToHex PROCEDURE(CONST *FILETIME Value)!,STRING
!   CODE 
!   RETURN LongToHex(Value.dwHighDateTime) & LongToHex(Value.dwLowDateTime)  


ODS PROCEDURE(STRING xMsg) 
sz CSTRING(SIZE(xMsg) + 1)
!sz  &CSTRING 
    CODE 
!    sz &= NEW CSTRING(LEN(xMsg) + 1) 
    sz = xMsg
    OutputDebugString(sz) 
!    DISPOSE(sz)

Thanks Mark, suspected as much.
Looking at svapi.inc shows a bunch of code dealing with COM objects that could potentially be helpful in the future, but as usual there’s no doc to go with it :frowning:

I’m definitely ready for 64 bit integers. They’re saying C12, but who knows.

Check out the i64.inc file in the meantime.

I’ve not heard of any native 64 types to ship with C12, but hey, who knows…

On the bug Mark points out, “the group seems more appropriate for a LARGE not a ULARGE
as both HiPart and LowPart are LONG” he is correct. I would not use these to do 64 bit math. For “data storage” though it works fine, since it’s just 8 bytes of ram. Get one API to set it, pass it to another API and you’ll be ok. (Frankly a String(8) would work for this as well.)

64 bit math is a different topic - for large integers (ie > 4 billion) I’ve just switched to using Reals. So not quite as big as an int64, but 15 significant digits, so big enough for what I need.

You could also maybe use DECIMAL as a middleperson for the math and then use the i64ToDecimal i64FromDecimal procedures as defined in i64.inc.

yeah, although Decimal math is quite slow compared to Real math.

cheers
Bruce

You missed the bit where I said “still using C6” :slight_smile:
In the meantime I’ll just sit here waiting for the community edition …

1 Like