Hi
I would like to ask you for help again.
I am trying to achive double buffering for console under Windows (I was in
shock when I noticed that there is double buffering for console).
My current code:
import winim
from os import execShellCmd, sleep
var buffer1: HANDLE = GetStdHandle(STD_OUTPUT_HANDLE)
var buffer2: HANDLE = CreateConsoleScreenBuffer( GENERIC_WRITE, 0, NULL,
CONSOLE_TEXTMODE_BUFFER, NULL)
discard execShellCmd("cls")
var begin: COORD
begin.X = 0;
begin.Y = 0;
SetConsoleCursorPosition(buffer1, begin)
var written: DWORD;
var s: wstring = `+$`[wstring]("milk!")
var s1: wstring = `+$`[wstring]("choco")
WriteConsole( buffer1, &s, 5, addr written, NULL)
echo "buffer 1"
WriteConsole( buffer2, &s1, 5, addr written, NULL)
proc open_osfhandle(osfhandle: Handle, flags: int): int {.importc:
"_open_osfhandle", header: "io.h".}
proc fdopen(fd: int, mode: char): FILE {.importc: "_fdopen", header:
"stdio.h".}
var fd = open_osfhandle(buffer1, 8)
echo "FD: ", fd
# This line produces error
# SIGSEGV: Illegal storage access. (Attempt to read from nil?)
# var f = fdopen(fd, 'a') # <- ERROR
#f.write("2 buf")
sleep(2000)
SetConsoleActiveScreenBuffer( buffer2 )
sleep(2000)
SetConsoleActiveScreenBuffer( buffer1 )
So I have found that required functions are fortunately wrapped in _winim_.
Fantastic, I could rewrite c++ code without almost any changes. And it works.
However, having this I would like to be able to just use standard _"write"_ Nim
procedure. Then the problems started to pile up. I need Nim _File_ having c
_HANDLE_. I have found that I can change _HANDLE_ to FILE* in c by obtaining
first file descriptor using __open_osfhandle_ and then get FILE* from FD using
__fd_open_. I tried but I find difficult to map c types to Nim and back. In
example code I have error. Could you help me?