node-ffi ref-struct question

884 views
Skip to first unread message

rhasson

unread,
Aug 23, 2012, 10:53:49 AM8/23/12
to nod...@googlegroups.com
Nathan, 

I started using node-ffi which works great.  I need to create some structs so I'm using ref-struct.  Now some of my structs have pointers to themselves like this:

typedef struct pst_block_recorder {
    struct pst_block_recorder  *next;
    int64_t                     offset;
    size_t                      size;
    int                         readcount;
} pst_block_recorder;

I tried to recreate this with ref-struct like this:
var pst_block_recorder = Struct ({
    //struct pst_block_recorder  *next;
    'next': ref.refType(pst_block_recorder),
    //int64_t                     offset;
    'offset': 'int64',
    //size_t                      size;
    'size': 'size_t',
    //int                         readcount;
    'readcount': 'int'
});

But I get the following error:
assert.js:102
  throw new assert.AssertionError({
        ^
AssertionError: could not determine a proper "type" from: undefined
    at Object.coerceType (/home/roy/node_modules/ref/lib/ref.js:389:3)
    at Object.refType (/home/roy/node_modules/ref/lib/ref.js:304:23)


I also tried making those struct fields "pointer" types but the C library doesn't seem to populate them correctly.

Any thoughts?

Thanks,
Roy

Nathan Rajlich

unread,
Aug 23, 2012, 12:34:26 PM8/23/12
to nod...@googlegroups.com
So basically when you're calling "ref.refType(pst_block_recorder)",
pst_block_recorder is still undefined. I ran into this problem with a
struct that libffi uses, and the solution is to progressively create
the struct instance using the "defineProperty()" function. Try
something like this:

var pst_block_recorder = Struct();
pst_block_recorder.defineProperty('next', ref.refType(pst_block_recorder));
pst_block_recorder.defineProperty('offset', 'int64');
pst_block_recorder.defineProperty('size', 'size_t');
pst_block_recorder.defineProperty('readcount', 'int');
> --
> Job Board: http://jobs.nodejs.org/
> Posting guidelines:
> https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
> You received this message because you are subscribed to the Google
> Groups "nodejs" group.
> To post to this group, send email to nod...@googlegroups.com
> To unsubscribe from this group, send email to
> nodejs+un...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/nodejs?hl=en?hl=en

rhasson

unread,
Aug 23, 2012, 12:55:55 PM8/23/12
to nod...@googlegroups.com
Good point.  I'll do that.


Another question, 
In C I do this:
typedef struct pst_file {
    pst_desc_tree  *d_head
} pst_file;

pst_desc_tree *d_ptr;  //this is another struct
d_ptr = pstfile.d_head;

How do I make this assignment with ref-struct?

Nathan Rajlich

unread,
Aug 23, 2012, 1:15:15 PM8/23/12
to nod...@googlegroups.com
> In C I do this:
> typedef struct pst_file {
> pst_desc_tree *d_head
> } pst_file;
>
> pst_desc_tree *d_ptr; //this is another struct
> d_ptr = pstfile.d_head;

It's a pointer to a struct actually. I think you need to explain more
what you intend to do with the variable after. Are you trying to make
a duplicate of the struct? It seems to me that what you have above
would be achieved with "pstfile.d_head.slice(0)" but I can't really
imagine what you would need that for.

rhasson

unread,
Aug 23, 2012, 4:50:52 PM8/23/12
to nod...@googlegroups.com
Sorry for not being very clear.  You're correct, pst_file is a struct with d_head being a pointer to another struct.  Within libpst (the C library I'm working with), when you call pst_open() you pass pst_file by reference which opens the PST file (MS outlook file) and populates the pst_file struct.  d_head is a pointer to another struct that holds individual records pulled out of the PST file.  When the pst_open() call returns I need to take the d_head pointer, assign it to another pointer variable of type pst_desc_tree and use that to pass into another function.

    pst_item *item = NULL;
    pst_desc_tree *d_ptr;

    pst_open(&pstfile, file_name, NULL);
    d_ptr = pstfile.d_head; // first record is main record
    item  = pst_parse_item(&pstfile, d_ptr, NULL);

The way I did it which seems to work is:

    var f = new pst_file();  //the main pst_file struct
    var pstdesctree_Ptr = ref.refType(pst_desc_tree);
    var d_ptr = ref.alloc(pstdesctree_Ptr);
    ref.writePointer(d_ptr, 0, f.d_head);

This seems to copy the correct pointer, however when I do:
ref.deref(d_ptr) 
I get a segmentation fault.
How would I get access to the variables stored in that struct inside node?

I didn't finish converting all the structs yet but give you an idea of what the code looks like.  In the SRC directory I included the .c and .h files so you can see the structures.

Thanks,
Roy

Nathan Rajlich

unread,
Aug 23, 2012, 5:27:33 PM8/23/12
to nod...@googlegroups.com
I think that whole step is unnecessary (saving the reference into a
"d_ptr" pointer). Just pass `f.d_head` directly to the
pst_parse_item() function.
Reply all
Reply to author
Forward
0 new messages