- Notifications
You must be signed in to change notification settings - Fork11
Importing libc in typescript
Let's write a simple program in typescript to take input from the user and greet, using only native C functions from libc.
Create a new project with
bun init
.Copy
libc.so.6
into your project directory.cp /lib64/libc.so.6 libc.so
We're renaming it because importing files ending with a number in the extension doesn't work yet.See here.
Inside index.ts, import these functions.
import{printf,gets,exit}from"./libc.so";import{ptr}from"bun:ffi";
You'll see the typescript error
Cannot find module
when importing from libc.so, don't worry, it gets fixed in the next steps.Let's define a function to convert a JS string to a C string.Learn why.
exportfunctioncstr(value:string){returnptr(newTextEncoder().encode(value+"\0"));}
Now let's allocate memory where we'll store the user input.
constname=Buffer.alloc(50);
Print the message asking the user to input their name.
printf(cstr("Enter your name: "));
Get the input from the user and store that in the buffer allocated earlier by passing the pointer of it.
gets(ptr(name));
Now, print the message to greet the user.
printf(cstr(`Hello,${name}`));
Exit the program with an exit code
0
.exit(0);
Your index.ts should now look like this.
import{printf,gets,exit}from"./libc.so";import{ptr}from"bun:ffi";exportfunctioncstr(value:string){returnptr(newTextEncoder().encode(value+"\0"));}constname=Buffer.alloc(50);printf(cstr("Enter your name: "));gets(ptr(name));printf(cstr(`Hello,${name}`));exit(0);
That's it. Now run
bun .
to run index.ts.You'll see this in your console saying the config file has been generated.
[HYPERIMPORT]: Library LoaderNo configuration was found for "/hypertest/libc.so"Config file has been generated at "/hypertest/@types/libc.so/config.ts"Edit the config.ts and set the argument and return types, then rerun the script.
Open the config.ts file and add the symbol definitions for the functions we imported earlier.
symbols:{printf:{args:[T.cstring],returns:T.void},gets:{args:[T.pointer],returns:T.void},exit:{args:[T.int],returns:T.void},}
We are done. Run
bun .
again to rerun the script.Enter your name and press enter.
The program works as expected. Entirely through native libc functions and not any javascript functions (excluding the code to convert strings and allocation).