Tôi đang cố gắng gọi hàm JS đã đăng ký khi gọi lại C++, nhưng tôi nhận được một segfault cho những gì tôi giả định là một vấn đề phạm vi.Gọi hàm Javascript từ cuộc gọi lại C++ trong V8
Handle<Value> addEventListener(const Arguments& args) {
HandleScope scope;
if (!args[0]->IsFunction()) {
return ThrowException(Exception::TypeError(String::New("Wrong arguments")));
}
Persistent<Function> fn = Persistent<Function>::New(Handle<Function>::Cast(args[0]));
Local<Number> num = Number::New(registerListener(&callback, &fn));
scope.Close(num);
}
Khi xảy ra sự kiện, phương pháp sau được gọi. Tôi giả định rằng điều này có thể xảy ra trên một chủ đề khác mà V8 đang thực hiện JS.
void callback(int event, void* context) {
HandleScope scope;
Local<Value> args[] = { Local<Value>::New(Number::New(event)) };
Persistent<Function> *func = static_cast<Persistent<Function> *>(context);
(* func)->Call((* func), 1, args);
scope.Close(Undefined());
}
Điều này gây ra một lỗi phân khúc: 11. Lưu ý rằng nếu tôi gọi hàm callback trực tiếp với một tham chiếu đến dai dẳng từ addEventListener(), nó thực hiện các chức năng một cách chính xác.
Tôi giả định rằng tôi cần một Locker hoặc Isolate? Nó cũng có vẻ như của libuv uv_queue_work() có thể có thể giải quyết điều này, nhưng kể từ khi tôi không bắt đầu thread, tôi không thể nhìn thấy cách bạn sẽ sử dụng nó.
Cảm ơn, điều này đơn giản hóa mã và khắc phục vấn đề phạm vi, nhưng tôi đã hy vọng một số thông tin cách gọi lại chủ đề chính từ chuỗi gọi lại. Tôi đã đạt được điều này bằng cách sử dụng chức năng eio_nop() từ thư viện EIO, nhưng cách ưu tiên là sử dụng libuv. Vấn đề của tôi là dường như không có một sự tương đương libuv của eio_nop. – marchaos
@marchaos Ok. Tôi đã không hoàn toàn rõ ràng những gì bạn đã sau khi bên luồng. Theo tôi hiểu nó, những gì bạn đang sau là có thể thực hiện JS từ callback trong bối cảnh chủ đề v8 chính. Tôi đã cùng nhau đưa ra một bản demo nhỏ về cách làm điều này với các cô lập/tủ khóa (https://gist.github.com/4341994). Lưu ý rằng điều này có nghĩa là bạn phải điều chỉnh ở mọi nơi bạn sử dụng V8 để khóa cô lập trước khi thực hiện bất kỳ điều gì khác! – je4d
Cảm ơn. Sẽ cung cấp cho điều này một đi, nhưng trông giống như cách tiếp cận đúng. – marchaos