On Jun 19, 2013, at 14:38, Nathan Rajlich wrote:
> I think you're close here... So one of the slightly confusing points is that Buffer instances already have 1 level of indirection by nature (they're a pointer to some process memory), so when you do:
>
> var lengthpointer = ref.alloc('uint *');
>
> You're really creating a Buffer that "can store a 'uint *'", so it itself is a "uint **" Buffer. Does that make sense? You're probably getting NaN for the length since when you call .deref() you're actually dereffing to a "uint *" Buffer, rather than a "uint" Number value.
>
> So on that note, try something like this (there's basically just 1 level of indirection removed from the variables):
>
> var mylib = ffi.Library('/path/to/mylib', {
> makeData: ['int', ['char **', 'uint *']],
> });
>
> var lengthpointer = ref.alloc('uint');
> var datapointer = ref.alloc('char *');
> mylib.makeData(datapointer, lengthpointer);
> var length = lengthpointer.deref();
> var data = ref.reinterpret(datapointer.deref(), length);
>
> Warning, untested! But let me know if that works out for you.
ref.alloc('uint') instead of ref.alloc('uint *') works. That's even what the Output Parameters section of the Tutorial wiki page says. I swear to you I spent hours yesterday trying every possible permutation without success. But thank you, that's clearly what I needed to do.
I think I got confused by the lone example, which seems to get it wrong:
https://github.com/rbranson/node-ffi/blob/master/example/sqlite.js
It declares the function as:
'sqlite3_open': [ 'int', [ 'string', sqlite3PtrPtr ] ],
Then allocates:
var db = ref.alloc(sqlite3PtrPtr)
Then calls:
SQLite3.sqlite3_open(dbName, db)
By what you wrote, shouldn't it instead allocate:
var db = ref.alloc(sqlite3Ptr)
A lot of my confusion was because:
* the Tutorial uses types like 'pointer'
* the only other wiki page, API Changes from v0.x to v1.x, says you should never use 'pointer' anymore and should always declare your own custom pointer types
* installing 'node-ffi' with npm gets you version 0.x that doesn't support custom pointer types; you have to install 'ffi' to get version 1.x
> FWIW I think you want a `datapointer.readCString()` call somewhere in there as well
I had been using data.toString() which worked. data.readCString() ended early with binary data. datapointer.readCString() didn't return anything.
> (instead of ref.reinterpret() perhaps?).
Not reinterpreting gave me only the first 8 bytes of data. I don't see how node could possibly know how much data is in the memory location being pointed to, unless I tell it by using reinterpret.
Thanks, I'm not sure I understand it though. But I think I'm all set for now.
Now I just need to make a test to see what the speed difference is between accessing the library via ffi and just running its command line program with spawn. My hope is that the pain of dealing with ffi yields a nice speed boost.