TooTallNate / ref

Turn Buffer instances into "pointers"
http://tootallnate.github.com/ref
453 stars 141 forks source link

How to represent char* in parameter that will be write by native function #81

Closed allanruin closed 6 years ago

allanruin commented 7 years ago

suppose there is a c function ,int get_my_value(const char* key, char* value); the second parameter is the value that should be return by function. I have not see practical example on web about how to read value fill by function to a parameter (which is common in C language). My current approach is

BUF_SIZE=4096;
var buf = new Buffer(BUF_SIZE);
buf.type =  ref.types.char;
var ret = ffi_wrapper_get_my_value("hello", buf);
//let ignore ret check
var result = buf.toString('utf8');

however, the result is a string that convert from buffer of size 4096, which, has a lot extra garbage value. Could anyone give me some tips about the elegant way to do this?

TooTallNate commented 6 years ago

This probably belongs in the node-ffi issue tracker, but anyways, you need to do something like:

const lib = ffi.Library({
  get_my_value: [ 'int', [ 'string', 'char*' ] ]
});

Since you said int was the return value, I'm assuming that's the number of bytes that was written to the value buffer. You need to use that value in the buf.toString() function so that the extra garbage after your string is not included.

Note that the first param is "string" because you want to marshal the JS string to C. But the second parameter is "char*" because you're passing in a raw Buffer that you want the C function to modify.

const BUF_SIZE=4096;
const buf = new Buffer(BUF_SIZE);
const bytesWritten = lib.get_my_value('hello', buf);
const result = buf.toString('utf8', 0, bytesWritten);

I hope that makes sense! Let me know if it doesn't work for you or you have more questions.