Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Callback TypeError: error setting return value - value is out of bounds #121

Closed
mojo3344 opened this issue Apr 19, 2013 · 2 comments
Closed

Comments

@mojo3344
Copy link

I'm new to node-ffi, and have been learning how to use callbacks, so this may be an understanding issue. But, I'm getting an odd error after a callback works with this test case:

var ffi = require('ffi')
var ref = require('ref')

// Interface into the native lib
var libLM = ffi.Library('./LMNodeLib', {
  'Object_new': [ "pointer", [] ],
  'Object_init': [ "void", [ "pointer" ] ],
  'Object_test': [ "int", [ "pointer", "pointer"] ],
  'Object_getDataByte': [ "int", [ "pointer", "int"] ]
})


// Callback from the native lib back into js
var callback = ffi.Callback('int', ['void *', 'int', 'string', 'string'], 
                            function (theObj, someInt, someStr1, someStr2) {  

    // access some values
    console.log("SomeInt: ", someInt)
    console.log("SomeStr1: ", someStr1)
    console.log("SomeStr2: ", someStr2)

    // Access the byte array in the object via a callback
    var i = 0
    while (i < 128) {
        if (libLM.Object_getDataByte(theObj,i) != i) {
            console.log("fail in callback")
        }

        i += 1
    }

    console.log("callback worked")
})

// make an extra reference to callback to avoid GC.
process.on('exit', function() {
    callback
});

var testObj = libLM.Object_new()
libLM.Object_init(testObj)
console.log("calling test")
libLM.Object_test(testObj, callback)
console.log('All done')

Here's my native lib:

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct {

    int state;
    unsigned char buf[128];

} Object_t, *Object_p;


void* Object_new() {
    void* obj = malloc(sizeof(Object_t));
    return obj;
}

void Object_init(Object_p self) {

    self->state = 5;
    int i = 0;
    while (i < 128) {
        self->buf[i] = i;
        i += 1;
    }
    printf("Object_init done\n");
}

typedef int (*callbackFP_t)(void* theObj, int theInt, char* theStr1, char* theStr2);
int Object_test(Object_p self, callbackFP_t fp) {

    unsigned char* dataPtr = (unsigned char*) self;

    int i = 0;
    while (i < 128) {

        if (self->buf[i] != i)
        {
            printf("FAIL\n");
            return 0;
        }
        i += 1;
    }

    // hit the callback
    printf("Hitting the callback\n");
    char buf1[256];
    strcpy(buf1, "the first string");
    (*fp)( (void*) self, 8, buf1, "second string");

    return 1;
}


int Object_getDataByte(Object_p self, int i) {
    return self->buf[i];
}

Which I compile with:
gcc -dynamiclib -undefined suppress -flat_namespace -g LMNodeLib.c -o LMNodeLib.dylib

It produces this output:

Object_init done
calling test
Hitting the callback
SomeInt:  8
SomeStr1:  the first string
SomeStr2:  second string
callback worked

/Users/morgan/shared/mojolabs/projects/js/node/node_modules/ffi/lib/_foreign_function.js:59
    bindings.ffi_call(cif, funcPtr, result, argsList)
             ^
TypeError: error setting return value - value is out of bounds
    at TypeError (<anonymous>)
    at checkInt (buffer.js:781:11)
    at SlowBuffer.Buffer.writeInt32LE (buffer.js:913:5)
    at Object.set (/Users/morgan/shared/mojolabs/projects/js/node/node_modules/ffi/node_modules/ref/lib/ref.js:920:52)
    at Object.set (/Users/morgan/shared/mojolabs/projects/js/node/node_modules/ffi/node_modules/ref/lib/ref.js:479:10)
    at /Users/morgan/shared/mojolabs/projects/js/node/node_modules/ffi/lib/callback.js:54:11
    at Object.ForeignFunction.proxy [as Object_test] (/Users/morgan/shared/mojolabs/projects/js/node/node_modules/ffi/lib/_foreign_function.js:59:14)
    at Object.<anonymous> (/Users/morgan/shared/mojolabs/projects/js/node/node-ffi/testCB/LMNodeLib.js:53:7)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)

Ie, the callback works, but the "all done" print never happens. For the record, I'm on OS X, node v0.10.0, and using ffi from npm, 1.2.5.

Not sure if this is a callback understanding issue on my part or a bug.

Any ideas?

@TooTallNate
Copy link
Member

Change the ffi.Callback return value to "void" instead of "int".

On Friday, April 19, 2013, Morgan Jones wrote:

I'm new to node-ffi, and have been learning how to use callbacks, so this
may be an understanding issue. But, I'm getting an odd error after a
callback works with this test case:

var ffi = require('ffi')
var ref = require('ref')

// Interface into the native lib
var libLM = ffi.Library('./LMNodeLib', {
'Object_new': [ "pointer", [] ],
'Object_init': [ "void", [ "pointer" ] ],
'Object_test': [ "int", [ "pointer", "pointer"] ],
'Object_getDataByte': [ "int", [ "pointer", "int"] ]
})

// Callback from the native lib back into js
var callback = ffi.Callback('int', ['void *', 'int', 'string', 'string'],
function (theObj, someInt, someStr1, someStr2) {

// access some values
console.log("SomeInt: ", someInt)
console.log("SomeStr1: ", someStr1)
console.log("SomeStr2: ", someStr2)

// Access the byte array in the object via a callback
var i = 0
while (i < 128) {
    if (libLM.Object_getDataByte(theObj,i) != i) {
        console.log("fail in callback")
    }

    i += 1
}

console.log("callback worked")

})

// make an extra reference to callback to avoid GC.
process.on('exit', function() {
callback
});

var testObj = libLM.Object_new()
libLM.Object_init(testObj)
console.log("calling test")
libLM.Object_test(testObj, callback)
console.log('All done')

Here's my native lib:

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct {

int state;
unsigned char buf[128];

} Object_t, *Object_p;

void* Object_new() {
void* obj = malloc(sizeof(Object_t));
return obj;
}

void Object_init(Object_p self) {

self->state = 5;
int i = 0;
while (i < 128) {
    self->buf[i] = i;
    i += 1;
}
printf("Object_init done\n");

}

typedef int (callbackFP_t)(void theObj, int theInt, char* theStr1, char* theStr2);
int Object_test(Object_p self, callbackFP_t fp) {

unsigned char* dataPtr = (unsigned char*) self;

int i = 0;
while (i < 128) {

    if (self->buf[i] != i)
    {
        printf("FAIL\n");
        return 0;
    }
    i += 1;
}

// hit the callback
printf("Hitting the callback\n");
char buf1[256];
strcpy(buf1, "the first string");
(*fp)( (void*) self, 8, buf1, "second string");

return 1;

}

int Object_getDataByte(Object_p self, int i) {
return self->buf[i];
}

Which I compile with:
gcc -dynamiclib -undefined suppress -flat_namespace -g LMNodeLib.c -o
LMNodeLib.dylib

It produces this output:

Object_init done
calling test
Hitting the callback
SomeInt: 8
SomeStr1: the first string
SomeStr2: second string
callback worked

/Users/morgan/shared/mojolabs/projects/js/node/node_modules/ffi/lib/_foreign_function.js:59
bindings.ffi_call(cif, funcPtr, result, argsList)
^
TypeError: error setting return value - value is out of bounds
at TypeError ()
at checkInt (buffer.js:781:11)
at SlowBuffer.Buffer.writeInt32LE (buffer.js:913:5)
at Object.set (/Users/morgan/shared/mojolabs/projects/js/node/node_modules/ffi/node_modules/ref/lib/ref.js:920:52)
at Object.set (/Users/morgan/shared/mojolabs/projects/js/node/node_modules/ffi/node_modules/ref/lib/ref.js:479:10)
at /Users/morgan/shared/mojolabs/projects/js/node/node_modules/ffi/lib/callback.js:54:11
at Object.ForeignFunction.proxy as Object_test
at Object. (/Users/morgan/shared/mojolabs/projects/js/node/node-ffi/testCB/LMNodeLib.js:53:7)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)

Ie, the callback works, but the "all done" print never happens. For the
record, I'm on OS X, node v0.10.0, and using ffi from npm, 1.2.5.

Not sure if this is a callback understanding issue on my part or a bug.

Any ideas?


Reply to this email directly or view it on GitHubhttps://github.com//issues/121
.

@mojo3344
Copy link
Author

That worked! I also tried adding a "return 1" to the end of the callback, and that also worked.

Thanks very much for spotting that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants