diff --git a/lib/ref.js b/lib/ref.js index 6d24375..e457bf9 100644 --- a/lib/ref.js +++ b/lib/ref.js @@ -746,8 +746,12 @@ exports.writeObject = function writeObject (buf, offset, obj) { exports.writePointer = function writePointer (buf, offset, ptr) { debug('writing pointer to buffer', buf, offset, ptr); - exports._writePointer(buf, offset, ptr); - exports._attach(buf, ptr); + // Passing true as a fourth parameter does an a stronger + // version of attach which ensures ptr is only collected after + // the finalizer for buf has run. See + // https://github.com/node-ffi-napi/ref-napi/issues/54 + // for why this is necessary + exports._writePointer(buf, offset, ptr, true); }; /** diff --git a/src/binding.cc b/src/binding.cc index d1fefbd..abd43ae 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -355,6 +355,18 @@ void WritePointer(const CallbackInfo& args) { if (input.IsNull()) { *reinterpret_cast(ptr) = nullptr; } else { + if ((args.Length() == 4) && (args[3].As() == true)) { + // create a node-api reference and finalizer to ensure that + // the buffer whoes pointer is written can only be + // collected after the finalizers for the buffer + // to which the pointer was written have already run + Reference* ref = new Reference; + *ref = Persistent(args[2]); + args[0].As().AddFinalizer([](Env env, Reference* ref) { + delete ref; + }, ref); + } + char* input_ptr = GetBufferData(input); *reinterpret_cast(ptr) = input_ptr; }