Bird
Raised Fist0
Denoframework~5 mins

FFI (Foreign Function Interface) for native code in Deno - Cheat Sheet & Quick Revision

Choose your learning style10 modes available
Recall & Review
beginner
What is FFI in the context of Deno?
FFI stands for Foreign Function Interface. It lets Deno call functions written in other languages like C or Rust, so you can use native code inside your Deno programs.
Click to reveal answer
beginner
How do you load a native library in Deno using FFI?
You use Deno.dlopen() with the path to the native library and a description of the functions you want to call. This creates a connection to the native code.
Click to reveal answer
intermediate
What is the purpose of the symbols object in Deno.dlopen()?
The symbols object tells Deno the names, parameter types, and return types of the native functions you want to use. It helps Deno understand how to call them correctly.
Click to reveal answer
intermediate
Why should you be careful when using FFI in Deno?
Because native code can crash your program or cause security risks if used incorrectly. FFI bypasses Deno's safety checks, so you must trust and test the native code well.
Click to reveal answer
beginner
Give a simple example of calling a native C function that adds two numbers using Deno FFI.
You load the library with Deno.dlopen(), define the add function with parameter and return types as 'i32', then call it like a normal function in JavaScript to get the sum.
Click to reveal answer
What does Deno.dlopen() do in FFI?
ARuns a Deno script in a sandbox
BCompiles TypeScript to JavaScript
CLoads a native library and prepares functions for use
DFetches data from the internet
Which of these is NOT a reason to use FFI in Deno?
ATo write pure JavaScript code
BTo access system-level features
CTo use fast native code
DTo reuse existing C or Rust libraries
What must you specify in the symbols object when using Deno.dlopen()?
AOnly function names
BOnly parameter names
COnly return types
DFunction names, parameter types, and return types
What is a risk of using FFI in your Deno program?
AProgram crashes or security issues
BSlower performance
CAutomatic memory management
DNo access to native code
Which language is commonly used with Deno FFI for native functions?
APython
BC or Rust
CJavaScript only
DHTML
Explain how you would call a native C function from Deno using FFI.
Think about loading, describing, and calling the native code.
You got /4 concepts.
    What are the main benefits and risks of using FFI in Deno?
    Consider why you would use FFI and what to watch out for.
    You got /2 concepts.

      Practice

      (1/5)
      1. What is the main purpose of using Deno.dlopen in Deno's FFI?
      easy
      A. To load a native shared library and access its functions
      B. To compile TypeScript code into JavaScript
      C. To start a web server in Deno
      D. To read files from the filesystem

      Solution

      1. Step 1: Understand the role of Deno.dlopen

        Deno.dlopen is used to load native shared libraries (like .dll, .so, .dylib) so Deno can call native functions.
      2. Step 2: Compare with other options

        Options B, C, and D relate to other Deno features but not FFI or native code loading.
      3. Final Answer:

        To load a native shared library and access its functions -> Option A
      4. Quick Check:

        Deno.dlopen loads native libraries = A [OK]
      Hint: Remember: dlopen means 'dynamic library open' [OK]
      Common Mistakes:
      • Confusing dlopen with file reading functions
      • Thinking dlopen compiles code
      • Mixing up server start with FFI loading
      2. Which of the following is the correct way to define a function signature for a native function returning an integer in Deno.dlopen?
      easy
      A. { myFunc: { parameters: ["i32"], result: "void" } }
      B. { myFunc: { parameters: ["i32"], result: "i32" } }
      C. { myFunc: { parameters: ["void"], result: "i32" } }
      D. { myFunc: { parameters: [], result: "string" } }

      Solution

      1. Step 1: Understand function signature format

        Function signatures in Deno.dlopen require specifying parameter types and the return type. For a function taking an integer and returning an integer, both parameters and result should be "i32".
      2. 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.
      3. Final Answer:

        { myFunc: { parameters: ["i32"], result: "i32" } } -> Option B
      4. Quick Check:

        Integer parameter and return = C [OK]
      Hint: Match parameter and result types exactly as strings [OK]
      Common Mistakes:
      • Using 'void' as a parameter type incorrectly
      • Mixing return and parameter types
      • Using unsupported types like 'string' without proper handling
      3. Given the following code snippet, what will be the output?
      const lib = Deno.dlopen("./libmath.so", {
        add: { parameters: ["i32", "i32"], result: "i32" }
      });
      
      const result = lib.symbols.add(10, 5);
      console.log(result);
      lib.close();
      medium
      A. undefined
      B. 105
      C. 15
      D. Runtime error

      Solution

      1. 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.
      2. 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.
      3. Final Answer:

        15 -> Option C
      4. Quick Check:

        Adding 10 + 5 = 15 [OK]
      Hint: Check parameter types and expected return for output [OK]
      Common Mistakes:
      • Concatenating numbers as strings (getting 105)
      • Forgetting to close the library
      • Assuming undefined return without checking signature
      4. Identify the error in this Deno FFI code snippet:
      const lib = Deno.dlopen("./libcalc.so", {
        multiply: { parameters: ["i32", "i32"], result: "i64" }
      });
      
      const output = lib.symbols.multiply(3, 4);
      console.log(output);
      lib.close();
      medium
      A. The result type should be "i32" instead of "i64"
      B. The parameters array should be empty
      C. The library path is incorrect
      D. The function call syntax is invalid

      Solution

      1. 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.
      2. 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.
      3. Final Answer:

        The result type should be "i32" instead of "i64" -> Option A
      4. Quick Check:

        Result type must match native function = D [OK]
      Hint: Match return type exactly with native function signature [OK]
      Common Mistakes:
      • Changing parameter types incorrectly
      • Assuming library path error without checking
      • Misusing function call syntax
      5. You want to call a native function that returns a pointer to a UTF-8 string. Which approach correctly handles this in Deno FFI?
      hard
      A. Define the function with result type "string" and use it directly
      B. Define the function with result type "i32" and convert to string
      C. Define the function with result type "void" and cast the result to string
      D. Define the function with result type "pointer", then use Deno.UnsafePointerView to read the string

      Solution

      1. 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.
      2. Step 2: Use Deno.UnsafePointerView to read UTF-8

        After getting the pointer, Deno.UnsafePointerView can read the memory as a UTF-8 string safely.
      3. Final Answer:

        Define the function with result type "pointer", then use Deno.UnsafePointerView to read the string -> Option D
      4. Quick Check:

        Pointer + UnsafePointerView for strings = B [OK]
      Hint: Use pointer type and UnsafePointerView for native strings [OK]
      Common Mistakes:
      • Using 'string' as result type directly
      • Casting void or integer to string incorrectly
      • Ignoring memory safety when reading pointers
      Recommended

      Ready to prove it?

      Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

      10 questions~5 mineasy hard