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?
The external library is supposed to write a string to that buffer, and then Deno reads its content
47 Replies
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:
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.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 🙂Thank you so much!
i try but dont work
try looking at lino's raylib bindings
maybe that will help you understand
GitHub
GitHub - lino-levan/raylib-deno: Deno FFI bindings for Raylib
Deno FFI bindings for Raylib. Contribute to lino-levan/raylib-deno development by creating an account on GitHub.
Thank you for helping me, but I didn't find an example of passing a parameter by reference with a string. The value changes when using a number, but not when using a string buffer.
I see
You'll need to give a bit more information than that; what is the C API / function type you're calling? What is the Deno FFI declaration you're using to call it?
i try call .so, there are 3 parameters
but the second and thirth is a pointer, the second receive the string and third len of string

"Integer" and "String" are not sufficient for me to know how this method should be called. Do you have any better documentation, eg.
int
or long uint
or uintptr_t
or such for the parameters?
Also, what is your Deno FFI declaration for the method like?
My guess would be that something like this would be correct:
@b0yediti0n fixed the above; I was hallucinating odd things about esTamanho
; this should now look a bit more reasonable.
We first get the sReposta
address and the es Tamanho
integer values using out pointers, then we turn sReposta
into a pointer and create an ArrayBuffer
from that pointer based on the es Tamanho
length. Then we use TextDecoder
to decode that buffer's byte contents into a string (this assumes the contents is UTF-8).i wil try thankyou
i was work in node with ffi,
i'm sorry i don't see your message previous
thankyou for helping, but the pointer string is not changed thankyou.

Okay, based on this the code should look a bit more like this:
But I don't exactly understand how the API is supposed work, so I don't really know if it's correct that the
sReposta
bytes stay as zero.if you want i send the dll or so
the api create and send fiscal notes (brasil), create XML, i try get the xml in sResposta
My apologies, but accepting DLLs over the Internet isn't really a thing I'm willing to do 🙂 I'm also not quite idle enough to start debugging this on my own.
i undertand, thankyou for helpme with your time
Based on this
int16_t NFE_ObterXml(int16_t AIndex, char **sResposta, int16_t *esTamanho)
it seems like the API expects to also return an i16
so that's something to consider / fix in the Deno FFI API declaration. What is that return value for, what does it mean? If it is an error code, then checking that might be useful. Perhaps the API is returning you an error that would explain why it's not writing to sReposta
?there are 3 int
return, to flag sucess or error
first arg, is queue of list xml
third arg, is the len total of sResposta, if the aloced sized is not enough to realoqued
Oh, ... hmm.... looking at this https://github.com/frones/ACBr/blob/master/Projetos/ACBrLib/Demos/Harbour/NFe/ACBrNFe.prg#L184 it seems like perhaps the C API string you used in Node is mistaken...? Or maybe I'm just misunderstanding it, but; it seems like the API expects you to preallocate a string buffer (which would normally be a
char *sReposta
) and tell the length of that buffer in esTamanho
. It will then write into that buffer IF it can fit all the data in it, and it tells you how many bytes it wants to write by writing to esTamanho
.GitHub
ACBr/Projetos/ACBrLib/Demos/Harbour/NFe/ACBrNFe.prg at master · fr...
Projeto ACBr - O branch master é um repositório espelho do SVN original (svn://svn.code.sf.net/p/acbr/code/trunk2), criado e mantido com git-svn. - frones/ACBr
is this lib you find
exectly
i'm sorry but not work
Right, that would've been useful information in the very beginning 🙂 So it's not a simple out-pointer but an in-out pointer. In that case this is how you work it:
i'm sorry
No worries 🙂
C APIs are really prickly friends; as a rule of thumb, every single piece of information possible is usually needed to figure out what on earth they mean 😄
thankyou for helping but don't work

sResposta is not filled after call funcion lib
Oh sorry, I forgot: gotta write the
DEFAULT_LENGTH
into esTamanho
before calling. I'll fix the text above.
Now it should hopefully work.I saw and corrected afeter print this cause the break, but in the same way, the sResposta is not changeded, the responde of function its not captured
i have the same code in python do you wante see?
If it goes into the if branch then it means that it needed more memory to write the data out, hence why it doesn't write anything into sReposta.
Sure
it not goes into the if the size is bigger
Bere?
Yeah, if the size is bigger then it should just write the data into sReposta.
GitHub
GitHub - B0yEditi0n/HERA_API: vim fazer um backup desse arquivo, a ...
vim fazer um backup desse arquivo, a documetnação e a criação estão ossos então cada passo é prezervado - B0yEditi0n/HERA_API
That is a repository
the response is empty
its my code
the same lib is calling but in python
Yes; if you want to show me where you use this particular API, please link it. Please don't make me search through the repository for that information.

sorry

Thanks, looks reasonable.
i'm brasilian do you need that i translate the comment or copy and past the code here?
Nah, I think I have it.
Thank you though ❤️
heiy, It is really buffer type or pointer type in the call ffi??
"buffer"
for the second and third.thank you
The above code hasn't really changed ~at all compared to the previous situation, but I at least cannot see what would be going wrong with it.
If it still does not work, can you tell me what the return value is and what does
esTamanhoValue
evaluate into?i don't belive, Work
THANK YOU
you save me