DEV Community

齊藤敦志
齊藤敦志

Posted on

Print to console with Chez Scheme and Windows console API.

On Windows, when print character to console via standard output, the character is interpret in current codepage. If encoding of a inner character string is different with current codepage, mojibake will happen. Encoding conversion is necessary.

And, it is impossible to print character that be not contained current codepage via standard output.

For print all unicode characters, we can use console API rather than standard output.

I made console output library with Chez Scheme's foreign interface and console API on Windows.

(library (console-port)
  (export open-console-output-port)
  (import (chezscheme))

  (define dummy (begin (load-shared-object "kernel32.dll") 1))

  (define-ftype handle void*)

  (define open-existing 3)

  (define create-file
    (foreign-procedure __stdcall "CreateFileW"
      (wstring unsigned-32 unsigned-32 void* unsigned-32 unsigned-32 void*)
      void*))

  (define file-share-write 2)

  (define generic-write #x40000000)

  (define (get-active-console-buffer)
    (create-file "CONOUT$" generic-write file-share-write 0 open-existing 0 0))

  (define write-console
    (foreign-procedure __stdcall "WriteConsoleW"
      (void* wstring unsigned-32 u32* void*)
      boolean))

  (define (open-console-output-port)
    (let ((output-handle (get-active-console-buffer))
          (vsize (make-bytevector 4)))
      (define (write-to-console string start count)
        (let ((str (substring string start (+ start count))))
          (write-console output-handle str count vsize 0)
          count))
      (make-custom-textual-output-port "console" write-to-console #f #f #f)))
  )
Enter fullscreen mode Exit fullscreen mode
(import (rnrs)
        (console-port))

(let ((port (open-console-output-port)))
  (display "あいうえお\nかきくけこ\n" port)
  (display "♘♞♙♕♟♝♜♗♛♚♖♔" port)
  (flush-output-port port)) ;; Do not forget the flash!!
Enter fullscreen mode Exit fullscreen mode

My windows computer is setted CP932. CP932 do not contain chess characters. But, it is printable by console API.

Unicode character printable

Discussion (0)