FFI lets your Deno code talk to programs written in other languages like C. This helps you use fast or special features not built into Deno.
FFI (Foreign Function Interface) for native code in Deno
const dylib = Deno.dlopen( "./mylib.so", // path to native library { "functionName": { parameters: ["i32", "f64"], result: "f64" }, }, ); const result = dylib.symbols.functionName(42, 3.14); dylib.close();
Use Deno.dlopen to load a native library file (like .so, .dll, or .dylib).
Define the functions you want to call with their parameter and return types.
add function that adds two integers.const dylib = Deno.dlopen("./libmath.so", { "add": { parameters: ["i32", "i32"], result: "i32" }, }); const sum = dylib.symbols.add(5, 7); console.log(sum); dylib.close();
strlen function to get string length from a pointer.const dylib = Deno.dlopen("./libstring.so", { "strlen": { parameters: ["pointer"], result: "usize" }, }); const ptr = new Uint8Array([72, 101, 108, 108, 111, 0]); const length = dylib.symbols.strlen(ptr); console.log(length); dylib.close();
This program loads a native library with a multiply function that multiplies two numbers. It calls the function and prints the result.
const dylib = Deno.dlopen("./libmath.so", { "multiply": { parameters: ["f64", "f64"], result: "f64" }, }); const a = 6.5; const b = 4.0; const product = dylib.symbols.multiply(a, b); console.log(`Product of ${a} and ${b} is ${product}`); dylib.close();
Make sure the native library file matches your operating system (.so for Linux, .dll for Windows, .dylib for macOS).
Always close the library with dylib.close() to free resources.
Parameter and result types must match the native function exactly to avoid errors.
FFI lets Deno call native code for extra speed or features.
Use Deno.dlopen to load libraries and define function signatures.
Always match types and close the library when done.
Practice
Deno.dlopen in Deno's FFI?Solution
Step 1: Understand the role of
Deno.dlopenDeno.dlopenis used to load native shared libraries (like .dll, .so, .dylib) so Deno can call native functions.Step 2: Compare with other options
Options B, C, and D relate to other Deno features but not FFI or native code loading.Final Answer:
To load a native shared library and access its functions -> Option AQuick Check:
Deno.dlopen loads native libraries = A [OK]
- Confusing dlopen with file reading functions
- Thinking dlopen compiles code
- Mixing up server start with FFI loading
Deno.dlopen?Solution
Step 1: Understand function signature format
Function signatures inDeno.dlopenrequire specifying parameter types and the return type. For a function taking an integer and returning an integer, both parameters and result should be "i32".Step 2: Analyze each option
{ myFunc: { parameters: ["i32"], result: "void" } } returns void, not integer. { myFunc: { parameters: ["void"], result: "i32" } } has parameters as void which is invalid. { myFunc: { parameters: [], result: "string" } } returns string but parameters are empty. Only { myFunc: { parameters: ["i32"], result: "i32" } } correctly matches integer parameter and integer return.Final Answer:
{ myFunc: { parameters: ["i32"], result: "i32" } } -> Option BQuick Check:
Integer parameter and return = C [OK]
- Using 'void' as a parameter type incorrectly
- Mixing return and parameter types
- Using unsupported types like 'string' without proper handling
const lib = Deno.dlopen("./libmath.so", {
add: { parameters: ["i32", "i32"], result: "i32" }
});
const result = lib.symbols.add(10, 5);
console.log(result);
lib.close();Solution
Step 1: Understand the function signature and call
The native function 'add' takes two 32-bit integers and returns a 32-bit integer. Calling add(10, 5) should return 15.Step 2: Analyze the output
The console.log prints the returned value, which is 15. No errors occur because the signature matches and the library is closed properly.Final Answer:
15 -> Option CQuick Check:
Adding 10 + 5 = 15 [OK]
- Concatenating numbers as strings (getting 105)
- Forgetting to close the library
- Assuming undefined return without checking signature
const lib = Deno.dlopen("./libcalc.so", {
multiply: { parameters: ["i32", "i32"], result: "i64" }
});
const output = lib.symbols.multiply(3, 4);
console.log(output);
lib.close();Solution
Step 1: Check function signature consistency
The function 'multiply' takes two 32-bit integers and likely returns a 32-bit integer. Using "i64" as result type can cause mismatch errors if the native function returns 32-bit.Step 2: Validate other parts
Parameters are correctly specified as two "i32". The library path and function call syntax are valid assuming the file exists and function is exported.Final Answer:
The result type should be "i32" instead of "i64" -> Option AQuick Check:
Result type must match native function = D [OK]
- Changing parameter types incorrectly
- Assuming library path error without checking
- Misusing function call syntax
Solution
Step 1: Understand pointer return handling
Native functions returning strings usually return pointers. Deno FFI requires defining the result as "pointer" to get the address.Step 2: Use
After getting the pointer,Deno.UnsafePointerViewto read UTF-8Deno.UnsafePointerViewcan read the memory as a UTF-8 string safely.Final Answer:
Define the function with result type "pointer", then use Deno.UnsafePointerView to read the string -> Option DQuick Check:
Pointer + UnsafePointerView for strings = B [OK]
- Using 'string' as result type directly
- Casting void or integer to string incorrectly
- Ignoring memory safety when reading pointers
Ready to prove it?
Pass the test and this pattern moves unknown
