Koromix / koffi

Fast and easy-to-use C FFI module for Node.js
https://koffi.dev/
MIT License
168 stars 3 forks source link

failed to get the value of 2-level-pointer( point to pointer) #166

Closed leo33853870 closed 1 week ago

leo33853870 commented 2 months ago

I am sorry that I do not speak English well. Here is the DLL(C) code and Koffi(NodeJS) Code.

int pPointer(int** datain)
{
    printf("DLL: %d\n", datain[0][0]);
    *datain[0] = 3;
    return *datain[0];
}
const pPointer = lib.func('int pPointer(_Inout_ int** datain)');
var datain = [[100]];
console.log("datain[0][0]:"+datain[0][0]);
pPointer(datain);//print 100
pPointer(datain);//print 3
console.log("datain[0][0]:"+datain[0][0]);//print undefined  -----------expected 3 here,and actually output "undefined"
Koromix commented 2 months ago

That's because while Koffi converts the parameter out back to nested JS arrays, the inner type is int * and Koffi gives you back a pointer encoded as an internal object (instead of a modified array).

This will work as you want:

const koffi = require('koffi');

const lib = koffi.load('./166.dll');
const pPointer = lib.func('int pPointer(_Inout_ int **datain)');

var datain = [[100]];
console.log("datain[0][0]:", datain[0][0]);
pPointer(datain);//print 100
pPointer(datain);//print 3

// After the call, datain[0] contains an External object which is how Koffi represents pointers
// Ask Koffi to decode it to an array of one int
datain[0] = koffi.decode(datain[0], 'int', 1);

console.log("datain[0][0]:", datain[0][0]);

A simpler way is to use an Int32Array inside the outer array, because this means Koffi does not have to convert anything back. The Int32Array pointer will be passed as-is to your C function, and modified directly, without Koffi having to convert back anything.

const koffi = require('koffi');

const lib = koffi.load('./166.dll');
const pPointer = lib.func('int pPointer(int **datain)');

var datain = [Int32Array.from([100])];
console.log("datain[0][0]:", datain[0][0]);
pPointer(datain);//print 100
pPointer(datain);//print 3
console.log("datain[0][0]:", datain[0][0]);