Author Topic: compile-conditional 32 or 64-bit variable declaration  (Read 4022 times)

0 Members and 1 Guest are viewing this topic.

Offline jack

  • Seasoned Forum Regular
  • Posts: 408
    • View Profile
compile-conditional 32 or 64-bit variable declaration
« on: April 10, 2019, 04:25:25 pm »
I asked a similar question at the defunct [abandoned, outdated and now likely malicious qb64 dot net website - don’t go there] forum and got some answers but unfortunately I forgot.
in the process of translating a C header, the need to declare a variable as LONG or _INTEGER64 depending on the OS arises quite frequently, I would like a solution that would work on Win32, Win64, Linux-32 and Linux64.
at first I thought that I could use _OFFSET for most cases but QB64 refuses to convert an _OFFSET to LONG for example.

Offline RhoSigma

  • QB64 Developer
  • Forum Resident
  • Posts: 565
    • View Profile
Re: compile-conditional 32 or 64-bit variable declaration
« Reply #1 on: April 10, 2019, 04:57:32 pm »
If you speak of a variable, i think you mean pointers, right? In case of a simple variable just use _INTEGER64, or LONG LONG in C/C++ headers, it will fit for the 32-bit version as well.

In case of a real pointer, you need the right pointer size for 32/64-bits, which is most easily done by using the predefined type "ptrszint" for those pointers in C/C++ headers. On the QB64 language level you would use _OFFSET for the respective pointers.

To get around the limitations of _OFFSET, which are imposed by QB64 only, not in C/C++, you may simply write a small wrapper function in the C/C++ header, which takes an _OFFSET and returns it back as _INTEGER64. Once again _INTEGER64 fits for 32-bit pointers as well.

I recommend you downloading my Libraries Collection, and closely analyze the content of the QB-StdLibs subfolder, especially the qbstdarg.h/.bi/.bm files, were i extensively had to deal with the 32/64-bits problem.
My Projects:   https://qb64forum.alephc.xyz/index.php?topic=809
GuiTools - A graphic UI framework (can do multiple UI forms/windows in one program)
Libraries - ImageProcess, StringBuffers (virt. files), MD5/SHA2-Hash, LZW etc.
Bonus - Blankers, QB64/Notepad++ setup pack

Offline jack

  • Seasoned Forum Regular
  • Posts: 408
    • View Profile
Re: compile-conditional 32 or 64-bit variable declaration
« Reply #2 on: April 10, 2019, 05:54:10 pm »
why does the following code not work as I expect?
testing on Windows 10 x64, QB64 32 and 64-bit
Code: QB64: [Select]
  1. o$ = _OS$
  2. $IF _OS$ = "[WINDOWS][64BIT]" THEN
  3.     PRINT "you are on Windows 64-bit"
  4. $ELSEIF _OS$ = "[WINDOWS][32BIT]" THEN
  5.     PRINT "you are on Windows 32-bit"
  6.     PRINT "you are on something else"
  7.  

Offline jack

  • Seasoned Forum Regular
  • Posts: 408
    • View Profile
Re: compile-conditional 32 or 64-bit variable declaration
« Reply #3 on: April 10, 2019, 06:05:00 pm »
never mind, this works
Code: QB64: [Select]
  1. $IF WIN AND 64BIT THEN
  2.     PRINT "you are on Windows 64-bit"
  3. $ELSEIF WIN AND 32BIT THEN
  4.     PRINT "you are on Windows 32-bit"
  5. $ELSEIF LINUX AND 64BIT THEN
  6.     PRINT "you are on Linux 64-bit"
  7. $ELSEIF LINUX AND 32BIT THEN
  8.     PRINT "you are on Linux 32-bit"
  9.     PRINT "you are on something else"
  10.  
« Last Edit: April 10, 2019, 06:34:20 pm by jack »

Offline jack

  • Seasoned Forum Regular
  • Posts: 408
    • View Profile
Re: compile-conditional 32 or 64-bit variable declaration
« Reply #4 on: April 11, 2019, 04:50:53 am »
To get around the limitations of _OFFSET, which are imposed by QB64 only, not in C/C++, you may simply write a small wrapper function in the C/C++ header, which takes an _OFFSET and returns it back as _INTEGER64. Once again _INTEGER64 fits for 32-bit pointers as well.

I recommend you downloading my Libraries Collection, and closely analyze the content of the QB-StdLibs subfolder, especially the qbstdarg.h/.bi/.bm files, were i extensively had to deal with the 32/64-bits problem.
hello RhoSigma
I looked at your libraries and noticed C/C++ header files, how are they used?
I mean, does QB64 automatically include them or do they need to be in a certain folder within QB64?
your suggestion of writing a wrapper interest me, but I need more how to information, thanks in advance :)

Offline RhoSigma

  • QB64 Developer
  • Forum Resident
  • Posts: 565
    • View Profile
Re: compile-conditional 32 or 64-bit variable declaration
« Reply #5 on: April 11, 2019, 09:23:08 am »
Hi Jack,

C/C++ header files are included into the program by defining a DECLARE LIBRARY function block. Taking my qbstdarg library as example you see there are 3 files, qbstdarg.h, qbstdarg.bi and qbstdarg.bm, which together built up the library.

As usual you've to $INCLUDE the .bi file at the beginning of a program and the .bm at the end. The .bi file usually contains required declarations such as CONST, DIM or DIM SHARED variables, TYPE defines and in this case DECLARE LIBRARY blocks, while the .bm file contains the SUBs and FUNCTIONs you later use in the program.

If you now take a look into qbstdarg.bi, then you will notice the DECLARE LIBRARY block which specifies the name of the C/C++ header file (but the path/name only without the actual .h extension) and within the block all subroutines/functions contained in the C/C++ are declared, so that QB64 knows how to call these functions. In general this is similar to using WinAPI calls or 3rd party .dll files, just instead of the name of a WinAPI/DLL (eg. kernel32) you specify the C/C++ header name. As you can also add a path here, there's no need to keep header files in a certain folder, just make sure your path is correct (best relative to the qb64 folder, if you wanna keep libraries in its own project folder inside the qb64 folder, as i do). With the function declarations inside the DECLARE LIBRARY block just make sure to use the right QB64 variable types for the result and arguments used in the C/C++ functions:

_BYTE (%%) = char or int8, _UNSIGNED _BYTE (~%%) = uchar or uint8
INTEGER (%) = int16, _UNSIGNED INTEGER (~%) = uint16
LONG (&) = int32, _UNSIGNED LONG (~&) = uint32
_INTEGER64 (&&) = int64, _UNSIGNED _INTEGER64 (~&&) = uint64
SINGLE (!) = float (don't get confused with QB64 _FLOAT here)
DOUBLE(#) = double
_FLOAT (##) = long double (not 100% sure here)

all these must be passed BYVAL, STRING and arrays otherwise are passed as reference, hence pointers (ie. without BYVAL). In C/C++ function argument lists you best use "ptrszint" for those arguments to automatically support 32/64 bit environments. However, you might need to cast the ptrszint into some real datatype in C/C++ to be able to work with it (eg: char* myString = (char*) givenStrArg, if the argument was declared like this in the header: myFunc(ptrszint givenStrArg) {.... code of the function ....}). Well, this is for selfmade strings (dynamically allocated within the header using malloc(), for real QB64 strings it's easier, as QB64 already know about its pointer and the compiler does the magic for 32/64 bits. A real STRING can be passed as is in C/C++
(eg. myFunc(char* givenStArg) .

Guess some questions are cleared now, but a lot more will arise now :), maybe if you're tell me what you're about to do, i can give some more specific details how to accomplish your goal.


My Projects:   https://qb64forum.alephc.xyz/index.php?topic=809
GuiTools - A graphic UI framework (can do multiple UI forms/windows in one program)
Libraries - ImageProcess, StringBuffers (virt. files), MD5/SHA2-Hash, LZW etc.
Bonus - Blankers, QB64/Notepad++ setup pack

Offline jack

  • Seasoned Forum Regular
  • Posts: 408
    • View Profile
Re: compile-conditional 32 or 64-bit variable declaration
« Reply #6 on: April 11, 2019, 09:30:56 am »
thank you very much for the detailed explanation :)
my project is very simple, make a gmp.bi https://gmplib.org for QB64
the problem is that integer types vary from platform to platform
« Last Edit: April 11, 2019, 09:36:15 am by jack »

Offline RhoSigma

  • QB64 Developer
  • Forum Resident
  • Posts: 565
    • View Profile
Re: compile-conditional 32 or 64-bit variable declaration
« Reply #7 on: April 11, 2019, 09:41:13 am »
Hi again,

well, if you're not intrested in doing C/C++ stuff on your own, but only want the wrapper function to convert _OFFSET into _INTEGER64, then here's the easy way for you:

1. make a C/C++ header file eg. "convoffset.h" and paste the following content into it:
Code: C: [Select]
  1. // --- Helper function to convert _OFFSET into _INTEGER64, which is not
  2. // --- possible on the QB64 language level.
  3. // ---------------------------------------------------------------------
  4. int64 OffToInt(ptrszint offs) {
  5.     return (int64) offs;
  6. }
  7.  
  8.  

2. in every program you need it, paste the following in the beginning of the program:
Code: QB64: [Select]
  1. DECLARE LIBRARY "convoffset" 'Do not add .h here !!
  2.     FUNCTION OffToInt&& (BYVAL offs%&)
  3.  
  4.  

3. use the function like this:
Code: QB64: [Select]
  1.  
  2. i = OffToInt&& (o)
  3.  
  4. 'or simply with type suffixes
  5.  
  6. i&& = OffToInt&& (o%&)
  7.  
  8.  

4. always make sure convoffset.h is along with your .bas files
« Last Edit: May 01, 2019, 10:54:08 pm by RhoSigma »
My Projects:   https://qb64forum.alephc.xyz/index.php?topic=809
GuiTools - A graphic UI framework (can do multiple UI forms/windows in one program)
Libraries - ImageProcess, StringBuffers (virt. files), MD5/SHA2-Hash, LZW etc.
Bonus - Blankers, QB64/Notepad++ setup pack

Offline jack

  • Seasoned Forum Regular
  • Posts: 408
    • View Profile
Re: compile-conditional 32 or 64-bit variable declaration
« Reply #8 on: April 11, 2019, 09:52:15 am »
what can I say but thanks, you made my day :)
will tackle this later in the day.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: compile-conditional 32 or 64-bit variable declaration
« Reply #9 on: April 11, 2019, 02:25:56 pm »
what can I say but thanks, you made my day :)
will tackle this later in the day.

Or, you can do it with MEM.  http://qb64.freeforums.net/thread/52/convert-offset-integer64
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline jack

  • Seasoned Forum Regular
  • Posts: 408
    • View Profile
Re: compile-conditional 32 or 64-bit variable declaration
« Reply #10 on: April 11, 2019, 05:55:27 pm »
@SMcNeill
interesting solution, however, it would be great if QB64 had an integer type that would be 32-bit on 32-bit OS and 64-bit on 64-bit OS, like _OFFSET but without the constraints.