Leokuma
Leokuma•13mo ago

FFI: How to pass a pointer to a char pointer?

How can I pass a pointer to a char pointer in order to use the C function below via FFI?
my_func(char **strp)
my_func(char **strp)
The external library is supposed to write a string to that buffer, and then Deno reads its content
3 Replies
Deno AI Helper
Deno AI Helper•13mo ago
The current FFI API in Deno does not support passing a pointer to a pointer directly. The supported types for parameters and results in FFI calls are: i8, u8, i16, u16, i32, u32, i64, u64, usize, f32, f64, void, pointer, buffer, function, and { struct: [...] }. However, you can pass a buffer (which is a TypedArray in JavaScript) to a C function. The C function can then treat this buffer as a pointer to a char array (i.e., char*). But for a char**, the current FFI API does not provide a direct way to handle this. Here's an example of how you can pass a buffer to a C function:
// ffi.ts
const library = Deno.dlopen("./mylib.so", {
my_func: {
parameters: ["buffer", "usize"],
result: "void",
},
});

const buffer = new Uint8Array(128); // allocate a buffer
library.symbols.my_func(buffer, buffer.length);
// ffi.ts
const library = Deno.dlopen("./mylib.so", {
my_func: {
parameters: ["buffer", "usize"],
result: "void",
},
});

const buffer = new Uint8Array(128); // allocate a buffer
library.symbols.my_func(buffer, buffer.length);
In this example, my_func is expected to fill the buffer with a string. After the call, you can convert the buffer to a string in JavaScript. Please note that this is a workaround and may not work for all use cases. If your C function specifically requires a char**, you might need to modify the C function to work with a char* or wait for more advanced features in Deno's FFI API.
AapoAlas
AapoAlas•13mo ago
Allocate 8 bytes of Uint8Array and pass that as parameter type "buffer" to the C call. After the call read the value from the Uint8Array as an unsigned 64 bit BigInt integer using either a DataView or a BigUint64Array create from the ArrayBuffer of the Uint8Array (uint8arr.buffer), and finally create a new pointer object using Deno.UnsafePointer.create(). Sorry it's a bit convoluted, FFI is a bit like that 🙂
Leokuma
LeokumaOP•13mo ago
Thank you so much!