Skip to content

ffi.Function underlying Callback is garbage collected #241

@BenoitZugmeyer

Description

@BenoitZugmeyer

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);
 }

 /**

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions