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', '[email protected]', '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)

4
  • 5
    Your question don't contain enough information to answer you, please take the time to do a proper minimal reproducible example and you will maybe solve your problem yourself ! wrapAsNative(callback) is probably wrong. Commented Apr 23, 2018 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. Commented Apr 24, 2018 at 5:34
  • 2
    You need to provide a gitrepo, else this like blind guess work Commented May 2, 2018 at 10:39
  • You need to share the code of /Lib.js file Line 130:26 Commented May 8, 2018 at 5:55

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

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 Arrays are not supported by ref-struct. You would have to go on a raw Buffer and address by offset manually.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.