Ошибка сегментации обратного вызова Node.js C++ async librarary(libvlc)

Я пытаюсь создать оболочку для libvlc для node.js (большинство из них устарели). LibLVC генерирует свои события асинхронно, но если я попытаюсь вызвать js callback в таком случае, он столкнется с ошибкой сегментации. Я нашел решения для libuv и AsyncWorker Нана, но ни один не может помочь.

Ошибка сегментации происходит в функции on_media_player_end_reached на Nan::MakeCallback(Nan::GetCurrentContext()->Global(), Nan::New(_cb), 0, 0);,

#include <node.h>
#include <nan.h>
#include <vlc/vlc.h>

namespace libvlc {

    using v8::Handle;
    using v8::Persistent;
    using v8::Function;
    using v8::FunctionCallbackInfo;
    using v8::Isolate;
    using v8::Local;
    using v8::Object;
    using v8::String;
    using v8::Value;
    using v8::Context;
    using v8::Primitive;
    using node::AtExit;

    int isPlaying = 1;

    libvlc_instance_t *inst;
    libvlc_media_player_t *mp;
    libvlc_media_t *m;
    libvlc_event_manager_t *evm;

    void Play(const FunctionCallbackInfo <Value> &args) {
        v8::String::Utf8Value str(args[0]->ToString());
        char *link = (char*) *str;

        m = libvlc_media_new_location(inst, link);
        libvlc_media_player_set_media(mp, m);
        libvlc_media_release(m);
        libvlc_media_player_play (mp);
    }

    static Nan::CopyablePersistentTraits<v8::Function>::CopyablePersistent _cb;

    void on_media_player_end_reached(const libvlc_event_t*, void *data) {
        Nan::MakeCallback(Nan::GetCurrentContext()->Global(), Nan::New(_cb), 0, 0);
        _cb.Reset();
    }

    void OnMediaPlayerEndReached(const Nan::FunctionCallbackInfo<Value> &args) {
        _cb = Nan::Persistent<Function>(args[0].As<Function>());
        libvlc_event_attach(evm, libvlc_MediaPlayerEndReached, on_media_player_end_reached, NULL);
    }

    void release_vlc(void *) {
        libvlc_media_player_release(mp);
        libvlc_release(inst);
    }

    void init(Local <Object> exports) {
        char const *vlc_argv[] = {"--no-video"};
        inst = libvlc_new(1, vlc_argv);
        mp = libvlc_media_player_new(inst);
        evm = libvlc_media_player_event_manager(mp);

        NODE_SET_METHOD(exports, "play", Play);
        Nan::SetMethod(exports, "onMediaPlayerEndReached", OnMediaPlayerEndReached);

        AtExit(release_vlc);
    }

    NODE_MODULE(libvlc, init)
}

РЕДАКТИРОВАТЬ: На основе этого ответа я обнаружил, что мне нужно уведомить цикл событий, в котором работает узел. Также я изменил код и теперь я получаю

FATAL ERROR: v8::HandleScope::CreateHandle() Cannot create a handle without a HandleScope
 1: node::Abort() [node]
 2: 0x12b82ac [node]
 3: v8::Utils::ReportApiFailure(char const*, char const*) [node]
 4: v8::internal::HandleScope::Extend(v8::internal::Isolate*) [node]
 5: v8::HandleScope::CreateHandle(v8::internal::Isolate*, v8::internal::Object*) [node]
 6: libvlc::async_cb_handler(uv_async_s*) [/mnt/old/home/martin/Projects/iaeste/prehravac/build/Release/vlc.node]
 7: 0x15671db [node]
 8: 0x15672b3 [node]
 9: 0x1577a48 [node]
10: uv_run [node]
11: node::Start(uv_loop_s*, int, char const* const*, int, char const* const*) [node]
12: node::Start(int, char**) [node]
13: __libc_start_main [/lib/x86_64-linux-gnu/libc.so.6]
14: 0x8f0111 [node]

Модифицированный код:

#include <node.h>
#include <nan.h>
#include <vlc/vlc.h>
#include <uv.h>

namespace libvlc {

    using v8::Handle;
    using v8::Persistent;
    using v8::Function;
    using v8::FunctionCallbackInfo;
    using v8::Isolate;
    using v8::Local;
    using v8::Object;
    using v8::String;
    using v8::Value;
    using v8::Context;
    using v8::Primitive;
    using node::AtExit;

    int isPlaying = 1;

    libvlc_instance_t *inst;
    libvlc_media_player_t *mp;
    libvlc_media_t *m;
    libvlc_event_manager_t *evm;

    uv_async_t async;

    void Play(const FunctionCallbackInfo <Value> &args) {
        v8::String::Utf8Value str(args[0]->ToString());
        char *link = (char*) *str;

        m = libvlc_media_new_location(inst, link);
        libvlc_media_player_set_media(mp, m);
        libvlc_media_release(m);
        libvlc_media_player_play (mp);
    }

    static Nan::CopyablePersistentTraits<v8::Function>::CopyablePersistent _cb;

    void on_media_player_end_reached(const libvlc_event_t*, void *data) {
        uv_async_send(&async);
        //Nan::MakeCallback(Nan::GetCurrentContext()->Global(), Nan::New(_cb), 0, 0);
        //_cb.Reset();
    }

    void OnMediaPlayerEndReached(const Nan::FunctionCallbackInfo<Value> &args) {
        _cb = Nan::Persistent<Function>(args[0].As<Function>());
        libvlc_event_attach(evm, libvlc_MediaPlayerEndReached, on_media_player_end_reached, NULL);
    }

    void release_vlc(void *) {
        libvlc_media_player_release(mp);
        libvlc_release(inst);
    }

    void async_cb_handler(uv_async_t *handle) {
        Nan::MakeCallback(Nan::GetCurrentContext()->Global(), Nan::New(_cb), 0, 0);
        _cb.Reset();
    }

    void init(Local <Object> exports) {
        char const *vlc_argv[] = {"--no-video"};
        inst = libvlc_new(1, vlc_argv);
        mp = libvlc_media_player_new(inst);
        evm = libvlc_media_player_event_manager(mp);

        uv_async_init(uv_default_loop(), &async, async_cb_handler);

        NODE_SET_METHOD(exports, "play", Play);
        Nan::SetMethod(exports, "onMediaPlayerEndReached", OnMediaPlayerEndReached);

        AtExit(release_vlc);
    }

    NODE_MODULE(libvlc, init)
}

0 ответов

Другие вопросы по тегам