5

これは、私が C++ で作成し、node-gyp を使用してビルドした node.js アドオン モジュールです。StoreFunction の場合、後で使用できるように関数へのポインターを保存しようとしています

InvokeFunction で後で呼び出そうとすると、セグメンテーション違反が発生します。両方の関数で (cout を使用して) ポインターを調べた場合、それらは同じ値であることに困惑しました。

したがって、2 つの関数を呼び出す間に呼び出しコンテキストが変更されるか、何を指しているのか理解できないと推測しています。

ここで私の問題について感謝して受け取ったすべての(うーん)ポインタ..............

#include <node.h>
#include <v8.h>

using namespace v8;
v8::Persistent<v8::Function> callbackFunction;
 Handle<Value> StoreFunction(const Arguments& args) {
    HandleScope scope;
    callbackFunction = *Local<Function>::Cast(args[0]);
    return scope.Close(Undefined());
}

Handle<Value> InvokeFunction(const Arguments& args) {
    HandleScope scope;
    Local<Value> argv[1] = { String::New("Callback from InvokeFunction")};
    callbackFunction->Call(Context::GetCurrent()->Global(), 1, argv);
    return scope.Close(Undefined());
}

void init(Handle<Object> target) {
  NODE_SET_METHOD(target, "StoreFunction", StoreFunction);
  NODE_SET_METHOD(target, "InvokeFunction", InvokeFunction);
}

NODE_MODULE(someaddonmodule, init);

そしてもちろん、js を呼び出すものもあります........

var myaddon = require('../build/Release/someaddonmodule');
myaddon.StoreFunction(function(data){   
    console.log("Called back: "+data);
});

myaddon.InvokeFunction();   //causes a segmentation fault
4

1 に答える 1

3

答えは、もう Java でプログラミングしていないからです。作成したポインターは、関数ではなくローカル ハンドルを指しています。これへの「参照」を保持するだけでは、スコープが閉じたときに V8 ガベージ コレクションがそれを破棄するのを止めるには不十分です。

これに対処するには、V8 に対して明示的な要求を行って、関数を保持するためのメモリを確保する必要があります。

Persistent< Function > percy;
Local<Function> callbackFunction = Local<Function>::Cast(args[0]);
percy = Persistent<Function>::New(callbackFunction);

V8の内部をよく理解している人がこれ以上知っている場合は、あなたの説明を聞きたいです:)

于 2014-02-10T12:00:01.637 に答える