15

I am trying to node-ffi library to call a cpp code.

CPP Code

typedef struct{
    char * key,
    char * value
} ContextAttribute;

typedef struct{
    ContextAttribute * attribute,
    int count
} Context;

This is used in

Status Init(     
    Handle* handle,       
    const char* id,    
    const char* token, 
    const char* apiKey,
    const char* productname,          
    const char* productVersion,        
    const char* productLanguage,       
    PlatformType platform,             
    const char* userGuid,              
    EventCb eventcb,
    Context * context
);

I am consuming the above cpp code by the following node-ffi javascript code

var ref = require('ref');
var ffi = require('ffi');
var Struct = require('ref-struct');

var ContextAttribute = new Struct({
    key: "string",
    value: "string"
});

var Context = new Struct({
    attribute: ref.refType(ContextAttribute),
    count: "int"
});

'Init': [Status, [
        ref.refType(voidPtr),
        'string',
        'string',
        'string',
        'string',
        'string',
        'string',
        PlatformType,
        'string',
        EventCb,
        ref.refType(Context)
    ]],

The function is called as under

this.Init(clientId, token, apiKey, productName, productVersion, productLanguage, platform, userGuid, Event, wrapAsNative(callback), Context)

I am trying to test this using

var context = [{
    attribute: [{
         key: 'os',
         value: 'win'
    }],
    count: 0
}];

var result = Lib.Init("myClient", testToken, '4d84247c36bd4f63977853eb1e0cb5b7', "asfasd",'12','en_US', 'MAC', 'abcd+1@pqr.com', 'SIGNIN', function(Handle, Event){
}, context);

I am getting the following error :

TypeError: error setting argument 10 - writePointer: Buffer instance expected as third argument at TypeError (native) at Object.writePointer (/Users/..../node_modules/ref/lib/ref.js:742:11) at Object.set (/Users/.../node_modules/ffi/ref/lib/ref.js:484:13) at Object.alloc (/Users/.../node_modules/ffi/lib/ref.js:516:13) at Object.proxy [as Init] (/Users/.../node_modules/ffi/lib/_foreign_function.js:50:22) at Object.Lib.Init (/Users/.../src/Lib.js:130:26)

AurA
  • 12,135
  • 7
  • 46
  • 63
  • 5
    Your question don't contain enough information to answer you, please take the time to do a proper [mcve] and you will maybe solve your problem yourself ! `wrapAsNative(callback)` is probably wrong. – Stargateur Apr 23 '18 at 10:08
  • wrapAsNative(callback) is correct (because I get no error if I don't pass the struct), I want to pass context object in Lib.init() function this context object(javascript) need to be compatible with above given Struct of C. – AurA Apr 24 '18 at 05:34
  • 2
    You need to provide a gitrepo, else this like blind guess work – Tarun Lalwani May 02 '18 at 10:39
  • You need to share the code of `/Lib.js` file Line 130:26 – sapy May 08 '18 at 05:55

1 Answers1

1
var context = [{
    attribute: [{
         key: 'os',
         value: 'win'
    }],
    count: 0
}];

That is not how you create a valid Buffer object with Context layout. You must use var context = new Context; to create a correctly typed object.

That's exactly what the error message tells you - context is not a valid Buffer.

Not sure about it, but I don't think ref supports C-style arrays either, so a pointer + count struct doesn't work like that. If you want to use them, you will have to do that on the C side, and treat the array as an opaque pointer type.

(Not actually true, it is possible. But it requires fiddling around with the offset parameter on the getand set methods of the raw Buffer instance.)

Linked lists do work though.

Ext3h
  • 5,713
  • 17
  • 43
  • seems to be a valid explaination, I will give your suggestion a try. One small doubt that still exists ... how to create Allocate memory for Array of Struct using node-ffi as you can see above attribute is array of struct. – AurA May 09 '18 at 11:21
  • @AurA Arrays are not supported by `ref-struct`. You would have to go on a raw `Buffer` and address by offset manually. – Ext3h May 09 '18 at 14:18