Consoles with C/C++ WebAssembly
stdio, stderr, and more
This section describes how to use twr-wasm in order to:
- create input/output consoles for use by C/C++
- direct stdin/stdout and stderr to a console
- use addressable display and canvas 2D consoles
- use multiple consoles at once
Quick Example
<body>
<div id="console-tag"></div>
<script type="module">
import {twrConsoleDiv, twrWasmModule} from "twr-wasm";
const tag=document.getElementById("console-tag");
const streamConsole=new twrConsoleDiv(tag);
const mod = new twrWasmModule({stdio: streamConsole});
await mod.loadWasm("./helloworld.wasm");
await mod.callC(["hello"]);
</script>
</body>
<body>
<div id="twr_iodiv"></div>
<script type="module">
import {twrWasmModule} from "twr-wasm";
const mod = new twrWasmModule();
await mod.loadWasm("./helloworld.wasm");
await mod.callC(["hello"]);
</script>
</body>
Running Examples
Name | View Live Link | Source Link |
---|---|---|
stdin and stdout to <div> |
View square demo | Source |
simple "terminal" via <canvas> |
View hello world demo | Source |
"cli" with a <canvas> stdio |
View CLI demo using libc++ | Source |
Multiple Consoles, including Canvas2D | View multi-io demo | Source |
Capabilities
With a Console you can:
- read character streams (Use C statements like
getc
orio_mbgets
) - write character streams (use C statements like
printf
orcout
) - position characters, graphics, colors with an addressable display (Use C statements like
io_setc32
orio_set_cursor
). - draw to a Canvas compatible 2D surface (Use C statements like
d2d_fillrect
).
Consoles are primarily designed for use by twr-wasm C/C++ modules, but they can also be used by JavaScript/TypeScript.
Although it is common to have a single console, an arbitrary number of consoles can be created, and they can be used by an arbitrary number of twr-wasm C/C++ modules.
Unicode characters are supported by consoles (see Character Encoding Support with twr-wasm).
Tag Shortcuts
If you add a <div id="twr_iodiv">
, a <canvas id="twr_iocanvas">
, or a <canvas id="twr_d2dcanvas">
tag to your HTML, twr-wasm will create the appropriate class for you when you instantiate the class twrWasmModule
or twrWasmModuleAsync
. Use these tag shortcuts as an aternative to instantiating the console classes in your JavaScript/TypeScript.
<div id="twr_iodiv">
will be used to create atwrConsoleDiv
asstdio
<canvas id="twr_iocanvas">
will be used to create atwrConsoleTerminal
asstdio
.<canvas id="twr_d2dcanvas">
will be used to create atwrConsoleCanvas
asstd2d
-- the default 2D drawing surface. See 2D drawing APIs.
If neither of the above <div>
or <canvas>
is defined in your HTML, and if you have not set stdio
via the io
or stdio
module options, then stdout
is sent to the debug console in your browser. And stdin
is not available.
Console Classes
Consoles are implemented in TypeScript and run in the JavaScript main thread. This allows consoles to be shared by multiple wasm modules.
For simple cases, when you use the tag shortcuts, you won't need to use these console classes directly. For more bespoke cases, they will come in handy. For details on console classes, see the TypeScript/JavaScript API reference
These conosle classes are available in twr-wasm:
twrConsoleDiv
streams character input and output to a div tagtwrConsoleTerminal
provides streaming or addressable character input and output using a canvas tag.twrConsoleDebug
streamings characters to the browser debug console.twrConsoleCanvas
creates a 2D drawing surface that the Canvas compatible 2d drawing APIs can be used with.
Multiple Consoles with Names
When you instantiate a class twrWasmModule
or twrWasmModuleAsync
, you can pass it the module option io
-- a javascript object containing name-console attributes. Your C/C++ code can then retrieve a console by name. This is described in more detail the TypeScript/JavaScript API Reference.
Also see the multi-io example.
Setting stdio and stderr
stdio
can be defined automatically if you use a Tag Shortcut. stderr
streams to the browser's debug console by default. Both can be set to a specific console with the module io
option.
For example, either of these will set stdio
to a streaming div
console:
const tag=document.getElementById("console-tag");
const streamConsole=new twrConsoleDiv(tag);
const mod = new twrWasmModule({stdio: streamConsole});
const mod = new twrWasmModule({ io: {stdio: streamConsole} });
This option would send stderr and stdio to the same console:
UTF-8 or Windows-1252
Consoles can support UTF-8 or Windows-1252 character encodings (see Character Encoding Support with twr-wasm).
C Access To Consoles
io_functions
io_functions
are available to operate on all character based Consoles.
d2d_functions
d2d_functions
are available to operate on Canvas 2D Consoles.
Reading from a Console
Reading from a console is blocking, and so twrWasmModuleAsync
must be used to receive keys. There are some specific requirements to note in the twrWasmModuleAsync
API docs.
You can get characters with any of these functions:
io_mbgets
- get a multibyte string from a console using the current locale character encoding. Console must support IO_TYPE_CHARREAD.twr_mbgets
- the same asio_mbgets
with the console set tostdin
.io_mbgetc
- get a multibyte character from antwr_ioconsole_t *
(akaFILE *
) likestdin
using the current locale character encodinggetc
(same asfgetc
) - get a single byte from aFILE *
(akatwr_ioconsole_t *
) -- returning ASCII or extended ASCII (window-1252 encoding)io_getc32
- gets a 32 bit unicode code point from antwr_ioconsole_t *
(which must support IO_TYPE_CHARREAD)
Standard C Library Functions
Many of the common standard C library functions, plus twr-wasm specific functions, are available to stream characters to and from the standard input and output console that supports character streaming (most do).
In C, a console is represented by twr_ioconsole_t
. In addition, FILE
is the same as a twr_ioconsole_t
(typedef twr_ioconsole_t FILE
). stdout
, stdin
, stderr
are all consoles.
#include <stdio.h>
to access stdout
, stdin
, stderr
, and FILE
.
FILE
is supported for user input and output, and for stderr. FILE
as filesystem I/O is not currently supported.
stdout and stderr functions
You can use these functions to output to the standard library defines stderr
or stdout
:
These functions go to stdout
:
Note that when characters are sent to the browser console using stderr
they will not render to the console until a newline, return, or ASCII 03 (End-of-Text) is sent.
For example:
A more common method to send output to the debug console is to use twr_conlog
. See General C API Section.