I'm trying to use a C library that stores some callbacks in an internal structure. I would like to use the ffi.Function type instead of ffi.Callback directly, so I can have a nicer JS library.
But it looks like the underlying ffi.Callback returned by ffi.Function.toPointer is being freed after a while (ffi fatal: callback has been garbage collected!).
I did a small use-case to reproduce my issue : https://gist.github.com/BenoitZugmeyer/886ce5c4aa4b3151c8fe
Below is a fix proposal working for me. The weakmap makes the Callback instance kept alive while the fn is not garbage collected. Obviously this patch is wrong as WeakMap is not in older versions of nodejs, and I'm sure it can be done more efficiently.
diff --git lib/function.js lib/function.js
index 30d5f90..5d23093 100644
--- lib/function.js
+++ lib/function.js
@@ -38,6 +38,7 @@ function Function (retType, argTypes, abi) {
this.retType = ref.coerceType(retType)
this.argTypes = argTypes.map(ref.coerceType)
this.abi = null == abi ? bindings.FFI_DEFAULT_ABI : abi
+ this.pointers = new WeakMap();
}
/**
@@ -70,7 +71,10 @@ Function.prototype.indirection = 1
*/
Function.prototype.toPointer = function toPointer (fn) {
- return Callback(this.retType, this.argTypes, this.abi, fn)
+ if (!this.pointers.has(fn)) {
+ this.pointers.set(fn, Callback(this.retType, this.argTypes, this.abi, fn));
+ }
+ return this.pointers.get(fn);
}
/**
I'm trying to use a C library that stores some callbacks in an internal structure. I would like to use the
ffi.Functiontype instead offfi.Callbackdirectly, so I can have a nicer JS library.But it looks like the underlying
ffi.Callbackreturned byffi.Function.toPointeris being freed after a while (ffi fatal: callback has been garbage collected!).I did a small use-case to reproduce my issue : https://gist.github.com/BenoitZugmeyer/886ce5c4aa4b3151c8fe
Below is a fix proposal working for me. The weakmap makes the
Callbackinstance kept alive while thefnis not garbage collected. Obviously this patch is wrong as WeakMap is not in older versions of nodejs, and I'm sure it can be done more efficiently.