Deno.UnsafeCallback Error (bypass string from c++ to deno)
I want to get string from c++.
(c++ -> deno works fine.)
I got error like this. in bellow code.
"[JS] Error in callback: TypeError: Failed to execute 'decode' on 'TextDecoder': Argument 1 is not an ArrayBuffer, SharedArrayBuffer, or a view on one"
Can anyone help me?
6 Replies
-------------------------------------
cpp
-------------------------------------
// callback function type
typedef void (callback_type)(int, const char);
callback_type callback = nullptr;
// set callback function
extern "C" void set_status_callback(callback_type cb) {
callback = cb;
}
extern "C" void print_two(const char* buff)
{
printf("[C++][%s] START\n", FUNCTION);
printf("[C++][%s] buff : '%s'\n", FUNCTION, buff);
callback(88, buff);
printf("[C++][%s] END\n", FUNCTION);
}
-------------------------------------
typescript
-------------------------------------
const ffi = Deno.dlopen("./fib.so", {
set_status_callback: { parameters: ["function"], result: "void", nonblocking: true },
print_two: { parameters: ["buffer"], result: "void", nonblocking: true },
} as const
);
const callback = new Deno.UnsafeCallback(
{ parameters: ["i32", "buffer"], result: "void" } as const, (age: number, msg: any) => {
try {
console.log(
[JS] #300
);
console.log([JS] age: ${age}
);
console.log(msg);
const decoder = new TextDecoder();
const str = decoder.decode(msg);
console.log(str);
console.log([JS] #400
);
}
catch (e) {
console.error([JS] Error in callback: ${e}
);
}
},
);
// Pass the callback pointer to dynamic library
ffi.symbols.set_status_callback(callback.pointer);
console.log('[JS] #100');
const buffer = new TextEncoder().encode("Hello World" + String.fromCharCode(0));
await ffi.symbols.print_two(buffer);
console.log('[JS] #200');
ffi.close();
export {};
------------------------------
This is output of deno code
------------------------------
[JS] #100
[C++][print_two] START
[C++][print_two] buff : 'Hello World'
[JS] #300
[JS] age: 88
[Object: null prototype] {}
[JS] Error in callback: TypeError: Failed to execute 'decode' on 'TextDecoder': Argument 1 is not an ArrayBuffer, SharedArrayBuffer, or a view on one
[C++][print_two] END
[JS] #200I wasn't able to find the answer to your question in the official Deno documentation. However, based on the error message you've provided, it seems like there might be an issue with the type of data you're passing to the
TextDecoder
's decode
method. The decode
method expects an argument that is an ArrayBuffer
, SharedArrayBuffer
, or a typed array view such as Uint8Array
.
If you're passing a string directly from C++ to Deno, make sure that the data is being transferred as one of the expected buffer types. If you're using a Deno FFI (Foreign Function Interface) binding or similar mechanism to call into C++ from Deno, double-check that the data type conversions are set up correctly.
Please note that this advice is not based on the Deno documentation, and I would advise you to double-check the accuracy of this advice. If you continue to experience issues, you might want to look into the specifics of how you're using FFI or the mechanism you're using to pass data from C++ to Deno, and ensure that the data is correctly formatted as a buffer type that TextDecoder
can handle.Ah, sorry it's a bit confusing but the FFI APIs will never provide you with a ready Uint8Array or ArrayBuffer or equivalent from the direction of native call to Deno: Simply put FFI cannot know how large the buffer should be. So
"buffer"
is essentially just an alias for "pointer"
in the return value position of symbols, or in the parameter position of callbacks.
The msg
should get a PointerValue
type if you remove the any
. This is essentially either null or an opaque JS object that carries the pointer inside it.
You can use Deno.UnsafePointerView.getCString
to turn that into a string directly.Thank you!! @Deno AI Helper @AapoAlas
You're welcome! If you have any more questions or need further assistance with Deno, feel free to ask. Good luck with your project!
No problem. Let me know if you find any more questions about FFI 🙂
Also if you didn't know yet, check out Denonomicon, and the WTF is FFI videos on Youtube