Я пытаюсь вызвать обратный вызов в V8 из другой точки моей функции. Так что этот кусок кода регистрации обратного вызова:Как вызвать обратный вызов javascript из C++
if (args.Length())
{
String::Utf8Value event(args[0]->ToString());
if (event.length())
{
Isolate* isolate = V8Interface::getCurrent()->getIsolate();
Locker locker(isolate);
HandleScope scope(isolate);
callback cb = callback(isolate, Local<Function>::Cast(args[1]));
if(!events.count(*event))
{
events[*event] = callbacks({ cb });
}
else
{
events.find(*event)->second.push_back(cb);
}
}
}
И это один называет его:
void trigger(std::string event)
{
Isolate* isolate = V8Interface::getCurrent()->getIsolate();
Locker locker(isolate);
HandleScope scope(isolate);
if(events.count(event))
{
for(callback cb : events.find(event)->second)
{
Local<Function> local = Local<Function>::New(isolate, cb);
local->Call(isolate->GetCurrentContext()->Global(), 0, {});
}
}
}
Функция триггера может быть вызвана в любом месте в любое время в моем коде C++. Я попытался простой пример (INIT v8 затем вызвать триггер), и я получаю:
#
# Fatal error in C:\OgreSDK\Projects\whitedrop\third_party\io.js\deps\v8\src/api.h, line 386
# CHECK(allow_empty_handle || that != 0) failed
#
Это моя главная:
Scribe::V8Interface v8Interface = Scribe::V8Interface();
v8Interface.initialize();
for(Whitedrop::WorldEvent* event : Whitedrop::worldEvents)
{
event->onStart();
}
Вы можете получить весь источник здесь:
https://github.com/whitedrop/whitedrop/tree/feature/v8
Line 386:
/**
* Create a local handle for the content of another handle.
* The referee is kept alive by the local handle even when
* the original handle is destroyed/disposed.
*/
V8_INLINE static Local<T> New(Isolate* isolate, Handle<T> that); // <<<<<<
V8_INLINE static Local<T> New(Isolate* isolate,
const PersistentBase<T>& that);
EDIT: Я пытался, благодаря Бен Noordhuis, как это:
Isolate* isolate = V8Interface::getCurrent()->getIsolate();
Locker locker(isolate);
HandleScope scope(isolate);
callback cb;
cb.Reset(isolate, Local<Function>::Cast(args[1]));
И называть:
Isolate* isolate = V8Interface::getCurrent()->getIsolate();
Locker locker(isolate);
HandleScope scope(isolate);
if(events.count(event))
{
for(callback cb : events.find(event)->second)
{
Local<Function> local = Local<Function>::New(isolate, cb);
local->Call(isolate->GetCurrentContext()->Global(), 0, {});
}
}
Но та же ошибка: '(
Выполняется ли этот код на основном потоке? – mscdex
думаю. Я загружу основной цикл. Во всяком случае, я ничего не сделал для реализации threading – Vinz243
Ошибка указывает, что ваш Isolate не знает о вашем Persistent. Является ли узел инициирующим обратный вызов из нового потока? Узнайте, вызывая v8 :: Isolate :: SetData() в вашей функции addWorldEvent(), затем проверяя, что данные все еще присутствуют в вашей функции trigger(). –