Author Topic: Best way to arrange an include.inc file?  (Read 3833 times)

0 Members and 1 Guest are viewing this topic.

Arnold

  • Guest
Best way to arrange an include.inc file?
« on: November 09, 2015, 12:44:05 AM »
Hi Charles,

working on the BCXgui project I wondered if there is a difference in compile-time by arranging the parts in an include file? I thought perhaps the order #define, const, macro, function / sub would be the best way? Should the functions / subs be sorted in a special order?

For declaring the WinApi functions I use this way:
...
! FindResource lib "kernel32.dll" alias "FindResourceA" (sys hModule, char* lpName, char* lpType) as sys
...

Would it make a difference if I use:

extern lib "kernel32.dll"
...
! FindResource alias "FindResourceA" (sys hModule, char* lpName, char* lpType) as sys
...
end extern

Probably the fastest way would be to use unprototyped functions but this I will do as a last step if everything works ok. Maybe I will use a DBcxfuncs.inc for debugging and Bcxfuncs.inc for the finished application.

Roland

Aurel

  • Guest
Re: Best way to arrange an include.inc file?
« Reply #1 on: November 09, 2015, 08:28:01 AM »
"kernel32.dll" is a part of windows ..so there is no need to call
external dll call....
of course if you use your own dll then yes.

Charles Pegge

  • Guest
Re: Best way to arrange an include.inc file?
« Reply #2 on: November 09, 2015, 09:12:41 AM »
Hi Roland,

the more efficient way, from the compiler's point of view, is to use an extern block, as in your second example. Omitting prototypes also saves compile-time work but is hazardous where integer/float mixes are likely to be encountered, or numerous arguments are required.

Peter

  • Guest
Re: Best way to arrange an include.inc file?
« Reply #3 on: November 09, 2015, 09:25:07 AM »
Quote
Would it make a difference if I use:

there is no difference!
Code: [Select]
include "asm.inc"
window 640,480,1
hdc = GetBufferDC

extern lib "kernel32.dll"
! SetPixelV Lib "gdi32.dll" (sys hdc, x, y, crColor) As sys
end extern

for i=0 to 639
     setpixelv hdc,i,100,0xffffff
next

waitkey
winExit


.

Arnold

  • Guest
Re: Best way to arrange an include.inc file?
« Reply #4 on: November 10, 2015, 01:40:07 AM »
Hi Charles,

thank you for the information. In the future I will use the extern block approach.

I would like to ask another question regarding types (in this case TBBUTTON). At Microsoft Technet I found this definition:

typedef struct {
  int       iBitmap;
  int       idCommand;
  BYTE      fsState;
  BYTE      fsStyle;
#ifdef _WIN64
  BYTE      bReserved[6];
#else
#if defined(_WIN32)
  BYTE      bReserved[2];
#endif
#endif
  DWORD_PTR dwData;
  INT_PTR   iString;
} TBBUTTON, *PTBBUTTON, *LPTBBUTTON;


in OxygenBasic\examples\WinGui\Toolbar1.o2bas you applied:

#ifdef _WIN32
 %n 2
#else
 %n 6
#endif

typedef struct {
  int       iBitmap;
  int       idCommand;
  BYTE      fsState;
  BYTE      fsStyle;
  BYTE      bReserved[n];
  sys   dwData;
  sys   iString;
} TBBUTTON, *PTBBUTTON, *LPTBBUTTON;


Is INT_PTR comparable with sys and is there a difference for sys in Win32 and Win64? I ask this because MSDN says:

#if defined(_WIN64)
 typedef __int64 INT_PTR;
#else
 typedef int INT_PTR;
#endif

Roland

Mike Lobanovsky

  • Guest
Re: Best way to arrange an include.inc file?
« Reply #5 on: November 10, 2015, 05:13:10 AM »
1. For a C99-compliant preprocessor, #ifdef X and #if defined(X) are 100% synonyms.

2.
Quote
Code: C
  1. #ifdef _WIN64
  2.   BYTE      bReserved[6];
  3. #else
  4.   #if defined(_WIN32)
  5.     BYTE      bReserved[2];
  6.   #endif
  7. #endif
  8.  

The array of bytes BYTE bReserved[n]; is used in this UDT (typedef in C parlance) for aligning its member fields on the machine-word boundary (4 bytes under x86, and 8 bytes, under x64).

Such a tree of preprocessor conditionals has three distinct branches:
  • if the _WIN64 preprocessor internal flag is defined under x64, the preprocessor is supposed to insert BYTE bReserved[6];
  • if the _WIN32 preprocessor internal flag is defined under x86, the preprocessor is supposed to insert BYTE bReserved[2];
  • if none of those flags are defined, for example under WinCE, the preprocessor is supposed to omit the alignment bytes from the structure declaration altogether.
3. OxygenBasic is (currently) designed to operate in _WIN32 and _WIN64 environments only therefore its preprocessor has to consider a two branch only choice and Charles' preprocessor directive is respectively simpler. It is supposed to use the alignment byte array either way and it only needs to change the array size placeholder n in between the square brackets to a numeric literal (either 2 or 6) as appropriate for the current platform.

4. OxygenBasic sys is an integer whose size adjusts itself automatically to 32 bits or 64 bits depending on the current platform. It is used in Charles' typedef to store the actual numeric values of the pointers DWORD_PTR and INT_PTR which may require up to 32 or 64 distinct non-zero bits in any random combination to be expressed correctly on the respective platform. So, you don't have to manually precise the size of these pointers in O2 specifically because sys would expand or shrink automagically by O2 design.
« Last Edit: November 10, 2015, 08:50:34 AM by Mike Lobanovsky »

Arnold

  • Guest
Re: Best way to arrange an include.inc file?
« Reply #6 on: November 10, 2015, 06:26:03 AM »
Hi Mike,

thank you for this information which is really helpful for me. I suspected such a behaviour but I was not sure. I think I now had a first glance at the real complexity of Win32 and Win64 programming and the magic which OxygenBasic uses.

Roland

Charles Pegge

  • Guest
Re: Best way to arrange an include.inc file?
« Reply #7 on: November 10, 2015, 08:59:06 AM »
Thanks Mike,

Quote
Such a tree of preprocessor conditionals has three distinct branches:•when the _WIN64 preprocessor internal flag is defined under x64, in which case the preprocessor is supposed to insert BYTE bReserved[6];
•when the _WIN32 preprocessor internal flag is defined under x86, in which case the preprocessor is supposed to insert BYTE bReserved[2];
•none of those flags are defined, for example under WinCE, in which case the preprocessor is supposed to omit the alignment bytes from the structure declaration altogether.

Normally, C struct alignment uses automatic padding so that 32 bit primitive members align to 4 byte boundaries, 64 bit members to 8 byte boundaries etc.

To eliminate automatic padding in any type, Oxygen uses keyword packed:

typedef struct
{
 byte b
 int  i
} ty

print sizeof ty '8 bytes

packed typedef struct
{
 byte b
 int  i
} ty

print sizeof ty '5 bytes



Mike Lobanovsky

  • Guest
Re: Best way to arrange an include.inc file?
« Reply #8 on: November 10, 2015, 09:43:03 AM »
Thanks, Charles!

Based on your input, your initial
Code: OxygenBasic
  1. #ifdef _WIN32
  2.   %n 2
  3. #else
  4.   %n 6
  5. #endif
  6.  
  7. typedef struct {
  8.   int       iBitmap;
  9.   int       idCommand;
  10.   BYTE      fsState;
  11.   BYTE      fsStyle;
  12.   BYTE      bReserved[n];
  13.   sys       dwData;
  14.   sys       iString;
  15. } TBBUTTON, *PTBBUTTON, *LPTBBUTTON;
  16.  

seems somewhat redundant for modern O2. I think the following typedef would do in O2 just as fine without the preprocessor macros altogether:
Code: OxygenBasic
  1. typedef struct {
  2.   int       iBitmap;
  3.   int       idCommand;
  4.   BYTE      fsState;
  5.   BYTE      fsStyle;
  6.   sys       dwData;
  7.   sys       iString;
  8. } TBBUTTON, *PTBBUTTON, *LPTBBUTTON;
  9.  

The Microsoft Technet typedef does seem redundant for a contemporary C too. An explicit bReserved[] field evidently dates back to when non-standardized C compiler implementations would not guarantee compliance with arguably yet non-existent default structure alignment rules, and is still kept in this typedef out of pure sentimental traditionalism. I just preferred not to stress it in my answer to Roland. :)
« Last Edit: November 10, 2015, 09:55:22 AM by Mike Lobanovsky »