Author Topic: Compliant 64-bit compiling  (Read 6134 times)

0 Members and 1 Guest are viewing this topic.

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 4268
    • Oxygen Basic
Re: Compliant 64-bit compiling
« Reply #30 on: December 13, 2019, 05:10:47 AM »
Hi Roland,

Yes, end extern is normally inserted after external declarations, and all functions and their declarations are considered 'internal' by default until the next 'extern' statement.

extern statement direct the compiler to use standard (DLL) calling conventions instead of the more efficient internal calling conventions.

Individual procedures are also made 'extern' by any of the following tags:
external extern callback export
« Last Edit: December 13, 2019, 05:25:24 AM by Charles Pegge »

Arnold

  • Hero Member
  • *****
  • Posts: 932
Re: Compliant 64-bit compiling
« Reply #31 on: December 15, 2019, 05:42:42 AM »
Hi Charles,

I found this code in /inc/crt/win32/stdio.bi of Freebasic v.1.07.1 and it makes me crazy:

...
#ifdef __FB_64BIT__
   declare function __iob_func() as FILE ptr
   #define stdin (@(__iob_func())[STDIN_FILENO])
   #define stdout (@(__iob_func())[STDOUT_FILENO])
   #define stderr (@(__iob_func())[STDERR_FILENO])
#else
   extern import _iob(0 to 2) alias "_iob" as FILE
   #define stdin (@_iob(STDIN_FILENO))
   #define stdout (@_iob(STDOUT_FILENO))
   #define stderr (@_iob(STDERR_FILENO))
#endif
...

I tried to port this to Oxygen but obviously I do it the wrong way:

Code: [Select]
$ Filename "Test_iob.exe"
'uses rtl32
'uses rtl64

uses corewin
uses console

indexbase 0

% STDIN_FILENO 0
% STDOUT_FILENO 1
% STDERR_FILENO 2

#ifndef mode64bit
//  extern import _iob(0 to 2) alias "_iob" as FILE
sys _iob = __p__iob()
sys stdin  = @_iob(STDIN_FILENO)
sys stdout = @_iob(STDOUT_FILENO)
sys stderr = @_iob(STDERR_FILENO)
#else
// declare function __iob_func() as FILE ptr
//    #define stdin  (@(__iob_func())[STDIN_FILENO])
//    #define stdout (@(__iob_func())[STDOUT_FILENO])
//    #define stderr (@(__iob_func())[STDERR_FILENO])
sys stdin  = call @__iob_func[STDIN_FILENO]
sys stdout = call @__iob_func[STDOUT_FILENO]
sys stderr = call @__iob_func[STDERR_FILENO]
#endif

printl stdin
printl stdout
printl stderr

printl "Enter"
waitkey

For 32-bit this will work but 64-bit crashes. I think I must do it similar like it was done using dispatch_table in o2scm.o2bas or was done in the demo \examples\Basics\FuncPointers1.o2bas. Although I tried some alternatives, somehow I cannot get any further. My logic is wrong and it seems that I am not flexible enough. Can you help?

Roland

Arnold

  • Hero Member
  • *****
  • Posts: 932
Re: Compliant 64-bit compiling
« Reply #32 on: December 15, 2019, 01:14:14 PM »
This will run in 32-bit and 64-bit mode, but probably there is a better solution:

Code: [Select]
$ Filename "Test_printf.exe"
'uses rtl32
'uses rtl64

uses corewin
uses console

indexbase 0

extern
! printf (char* a, ...) at @printf

% STDIN_FILENO 0
% STDOUT_FILENO 1
% STDERR_FILENO 2

type FILE
char* _ptr
int _cnt
char* _base
int _flag
int _file
int _charbuf
int _bufsiz
char* _tmpfname
end type

#define _O_TEXT 0x4000 // CRLF in file becomes LF in memory!
#define _IONBF  0x4

#ifndef mode64bit
//  extern import _iob(0 to 2) alias "_iob" as FILE
FILE* _iob = __p__iob()
sys stdin  = @_iob(STDIN_FILENO)
sys stdout = @_iob(STDOUT_FILENO)
sys stderr = @_iob(STDERR_FILENO)
#else
// declare function __iob_func() as FILE ptr
sys stdin  = call @__iob_func()
sys stdout = stdin + sizeof(FILE)
sys stderr = stdout + sizeof(FILE)
#endif

'printl stdin
'printl stdout
'printl stderr + cr

sys hCrt = _open_osfhandle(ConsOut, _O_TEXT)
sys hf   = _fdopen(hCrt, "w")
memcpy  stdout, hf, sizeof(FILE)
setvbuf stdout, NULL, _IONBF, 0

fprintf(stdout, "loading %s" + chr(10), "Testfile.txt")
fprintf(stdout, "Oxygen ")
printf (chr(10) + "OxygenBasic")

printl "Enter"
waitkey

It should be possible to create a __iob_func() table, but I do not know how this can be done.

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 4268
    • Oxygen Basic
Re: Compliant 64-bit compiling
« Reply #33 on: December 16, 2019, 05:33:19 AM »
Hi Roland,

This works for 64bit:

Code: [Select]
#ifndef mode64bit
//  extern import _iob(0 to 2) alias "_iob" as FILE
FILE* _iob = __p__iob()
sys stdin  = @_iob(STDIN_FILENO)
sys stdout = @_iob(STDOUT_FILENO)
sys stderr = @_iob(STDERR_FILENO)
#else
// declare function __iob_func() as FILE ptr
FILE* _iob = __iob_func()
sys stdin  = @_iob(STDIN_FILENO)
sys stdout = @_iob(STDOUT_FILENO)
sys stderr = @_iob(STDERR_FILENO)
'sys stdin  = __iob_func()
'sys stdout = stdin + sizeof(FILE)
'sys stderr = stdout + sizeof(FILE)
#endif

Mike Lobanovsky

  • Admin Support Member
  • *****
  • Posts: 1993
Re: Compliant 64-bit compiling
« Reply #34 on: December 16, 2019, 08:47:57 AM »
... or this: ;)

Code: [Select]
#ifndef mode64bit
FILE* _iob = __p__iob()
#else
FILE* _iob = __iob_func()
#endif

sys stdin  = @_iob(STDIN_FILENO)
sys stdout = @_iob(STDOUT_FILENO)
sys stderr = @_iob(STDERR_FILENO)
Mike
(3.6GHz Intel Core i5 Quad w/ 16GB RAM, nVidia GTX 1060Ti w/ 6GB VRAM, Windows 7 Ultimate Sp1)

Arnold

  • Hero Member
  • *****
  • Posts: 932
Re: Compliant 64-bit compiling
« Reply #35 on: December 17, 2019, 02:05:04 AM »
Many thanks. This is far better than my trial and error and will help to understand simiiar constructs. And I now can see that the procedure was already described in /Console/Printf.o2bas. I adapted Printf.o2bas a bit and it runs fine in 32-bit and 64-bit:

Code: (o2) [Select]
$filename "printf.exe"
'uses rtl32
'uses rtl64

'Getting printf to operate in JIT mode
======================================

'Thanks to Mike Lobanovsky
'12:28 07/10/2014

#console
'%NoConsole
%TryAttachConsole

uses corewin
uses console

indexbase 0

' _iob[FOPEN_MAX] is msvcrt's internal file buffer array.
' _iob[] can be exported directly, or via cdecl __p__iob(), or via cdecl __iob_func().
' Reference:
' #define FOPEN_MAX     20
' #define STDIN_FILENO  0
' #define STDOUT_FILENO 1
' #define STDERR_FILENO 2
' #define stdin         &_iob[STDIN_FILENO]
' #define stdout        &_iob[STDOUT_FILENO]
' #define stderr        &_iob[STDERR_FILENO]

% STDIN_FILENO 0
% STDOUT_FILENO 1
% STDERR_FILENO 2


type FILE
char* _ptr
int   _cnt
char* _base
int   _flag
int   _file
int   _charbuf
int   _bufsiz
char* _tmpfname
end type

/*
extern cdecl lib "msvcrt.dll"
! __p__iob        () as sys
! _open_osfhandle (sys a, b) as sys
! _fdopen         (sys a, char* b) as sys
! setvbuf         (sys a, char* b, sys c, d)
! fprintf         '(sys a, char* b, ...)
! printf          '(char* a, ...)
! memcpy          (sys a, b, c)
end extern
*/

#define _O_TEXT 0x4000 // CRLF in file becomes LF in memory!
#define _IONBF  0x4

' same for ConsIn/"r", ConsErr/"w"
sys hCrt = _open_osfhandle(ConsOut, _O_TEXT)
sys hf   = _fdopen(hCrt, "w")

' user-defined buffer (for fprintf() only!)
FILE mystdout at hf
setvbuf @mystdout, NULL, _IONBF, 0

' _iob's internals:
' stdin at _iob as "r",
' stdout at iob+sizeof(FILE) as "w"
' stderr at _iob+2*sizeof(FILE) as "w"
'sys _iob = __p__iob()
#ifndef mode64bit
FILE* _iob = __p__iob()
#else
FILE* _iob = __iob_func()
#endif

sys stdin  = @_iob(STDIN_FILENO)
sys stdout = @_iob(STDOUT_FILENO)
sys stderr = @_iob(STDERR_FILENO)

memcpy stdout, hf, sizeof(FILE)
setvbuf stdout, NULL, _IONBF, 0

% lf = chr(10)

fprintf @mystdout, "fprintf via mystdout: %s and his %s%d" + lf, "Charles", "O", 2
fprintf stdout, "fprintf via stdout  : %s and his %s%d" + lf, "Charles", "O", 2
printf "printf  via stdout  : %s and his %s%d" + lf, "Charles", "O", 2

waitkey

I guess that as long as msvcrt.dll is supported, there will be many useful additional functions available which help in programming.
« Last Edit: December 17, 2019, 02:15:31 AM by Arnold »

Mike Lobanovsky

  • Admin Support Member
  • *****
  • Posts: 1993
Re: Compliant 64-bit compiling
« Reply #36 on: December 18, 2019, 04:06:35 AM »
I guess msvcrt.dll, the oldest one, will be supported forever as there are millions of apps linked against that runtime. Conversely, later incarnations are bound to specific MS VC builds/versions and live only as long as those versions are in use until superseded.
Mike
(3.6GHz Intel Core i5 Quad w/ 16GB RAM, nVidia GTX 1060Ti w/ 6GB VRAM, Windows 7 Ultimate Sp1)