4

OK、JavaScriptから呼び出す必要のあるC ++の関数があり、パラメーターの1つはJavaScriptオブジェクトです。JavaScriptは次のようになります。

var message = {
    fieldA: 42,
    fieldB: "moo"
};

myObj.send(message, function (err) { console.log("Result: " + err); });

send()ルーチンで、ブロックする可能性のある別のCライブラリのネイティブ関数を呼び出す必要があります。このライブラリのすべての関数がブロックされる可能性があるため、私はuv_queue_workを広範囲に使用しています。

このルーチンは私が問題にぶつかったのは初めてであり、JavaScriptオブジェクトが原因です。C++コードは次のようになります。

struct SendMessageRequest
{
    Persistent<Object> message;
    Persistent<Function> callback;
    int result;
};

Handle<Value> MyObj::Send(const Arguments& args)
{
    HandleScope scope;

    // Parameter checking done but not included here
    Local<Object> message = Local<Object>::Cast(args[0]);
    Local<Function> callback = Local<Function>::Cast(args[1]);

    // Send data to worker thread
    SendMessageRequest* request = new SendMessageRequest;
    request->message = Persistent<Object>::New(message);
    request->callback = Persistent<Function>::New(callback);

    uv_work_t* req = new uv_work_t();
    req->data = request;

    uv_queue_work(uv_default_loop(), req, SendMessageWorker, SendMessageWorkerComplete);

    return scope.Close(Undefined());
}

これはすべて問題ありません。SendMessageWorker関数でrequest->messageにアクセスしようとすると問題が発生します。

void SendMessageWorker(uv_work_t* req)
{
    SendMessageRequest* request = (SendMessageRequest*)req->data;
    Local<Array> names = request->message->GetPropertyNames();
    // CRASH

request-> messageからメソッドを呼び出すと、非常に小さいアドレス(おそらく、V8 /ノードのどこかでNULLポインター参照)でアクセス違反が発生するようです。したがって、request->messageを直接使用することは間違っている必要があります。私はこれを行う必要があるコールバック関数にアクセスすることを知っています:

request->callback->Call(Context::GetCurrent()->Global(), 1, argv);

PersistentテンプレートによってラップされているObjectクラスのメソッドにアクセスするには、Context :: GetCurrent()-> Global()を使用する必要がありますか?もしそうなら、どうすればいいですか?

4

1 に答える 1

4

のコードSendMessageWorkerはJavaScriptで実行されません。つまり、別のスレッドでuv_queue_work実行SendMessageWorkerされるため、node.jsコードも実行でき、準備ができたらSendMessageWorkerCompleteJavaScriptスレッドで実行されます。

したがって、SendMessageWorkerでJavaScript変数を使用することはできません。本当に必要な場合は、を呼び出す前に、JavaScript変数をC++文字列などに変換する必要がありますuv_queue_work

于 2012-06-19T23:33:13.147 に答える