2013-07-05 2 views
3

Я работаю над обновлением node-mapserver что облегает mapserver библиотеку в class-refactor ветви к более обслуживаемой структуре коды (исходя из моих изменений в организациях node-ogr).выполнение класса отказа оберточный C объект

До сих пор я обновил интерфейс основного модуля и начал работу над первым классом, который должен быть обернут, maperver C struct с именем errorObj, который я обертываю class MSError. Строка расширения, но я сталкиваюсь с ошибкой утверждения времени выполнения в расширении при первом запуске нового объекта MSError для обертывания errorObj.

Fatal error in ../deps/v8/src/api.h, line 297 
CHECK(allow_empty_handle || that != __null) failed 

С узлом 0,10 есть чрезвычайно длительный трассировки стека после этого, которые можно увидеть в travis build 27.2. Я не мог найти ничего особенно полезного в трассировке стека.

Расширение сборки и некоторые тесты проходят (символы и методы экспортируются из самой библиотеки), но не удается, когда библиотека пытается создать объект, который обертывает объект C.

В javascript, я звоню mapserver.getError(). В расширении это вызывает метод maperver errorObj* err = msGetErrorObj(); и возвращается с return scope.Close(MSError::New(err));. Метод MSError New делает это:

Handle<Value> MSError::New(errorObj *err) { 
    HandleScope scope; 
    MSError *wrapped = new MSError(err); 
    Handle<Value> ext = External::New(wrapped); 
    Handle<Object> obj = MSError::constructor->GetFunction()->NewInstance(1, &ext); 
    return scope.Close(obj); 
} 

Я пытался отладить это с помощью GDB, лучшее, что я могу выйти из него с моими ограниченными навыками является то, что ошибка происходит в этом вызове:

Handle<Object> obj = MSError::constructor->GetFunction()->NewInstance(1, &ext); 

Что я могу собрать из этого, так это то, что ext имеет значение null, что означает, что вызов External::New(wrapped) не возвращает действительное значение. Я подтвердил, что errorObj* err указывает на действительную, правильно инициализированную структуру errorObj. Чтобы уточнить, нет никакой реальной ошибки, maperver всегда возвращает допустимый errorObj, но с кодом 0, если в это время ошибки нет.

Здесь, надеюсь, соответствующий код.

ms_error.hpp

#ifndef __NODE_MS_ERROR_H__ 
#define __NODE_MS_ERROR_H__ 

#include <v8.h> 

#include <node.h> 
#include <node_object_wrap.h> 

#include <mapserver.h> 

using namespace v8; 
using namespace node; 

class MSError: public node::ObjectWrap { 
    public: 
    static Persistent<FunctionTemplate> constructor; 
    static void Initialize(Handle<Object> target); 
    static Handle<Value> New(const Arguments &args); 
    static Handle<Value> New(errorObj *err); 

    MSError(); 
    MSError(errorObj *err); 
    inline errorObj *get() { return this_; } 

    private: 
    ~MSError(); 
    errorObj *this_; 
}; 

#endif 

ms_error.cpp

#include "ms_error.hpp" 

Persistent<FunctionTemplate> MSError::constructor; 

void MSError::Initialize(Handle<Object> target) { 
    HandleScope scope; 

    constructor = Persistent<FunctionTemplate>::New(FunctionTemplate::New(MSError::New)); 
    constructor->InstanceTemplate()->SetInternalFieldCount(1); 
    constructor->SetClassName(String::NewSymbol("MSError")); 

    // constructor->InstanceTemplate()->SetNamedPropertyHandler(MSError::NamedPropertyGetter, NULL, MSError::NamedPropertyQuery, NULL, MSError::NamedPropertyEnumerator); 

    target->Set(String::NewSymbol("MSError"), constructor->GetFunction()); 
} 

MSError::MSError(errorObj *err) : ObjectWrap(), this_(err) { } 

MSError::MSError() : ObjectWrap(), this_(0) { } 

MSError::~MSError() { } 

Handle<Value> MSError::New(const Arguments& args) 
{ 
    HandleScope scope; 

    if (!args.IsConstructCall()) 
    return ThrowException(String::New("Cannot call constructor as function, you need to use 'new' keyword")); 

    if (args[0]->IsExternal()) { 
    Local<External> ext = Local<External>::Cast(args[0]); 
    void *ptr = ext->Value(); 
    MSError *f = static_cast<MSError *>(ptr); 
    f->Wrap(args.This()); 
    return args.This(); 
    } 

    return args.This(); 
} 

ответ

2

Ответ на этот вопрос является то, что приведенный выше код является штраф. Фактическая ошибка заключалась в том, что конструктор MSError :: не был инициализирован, потому что я забыл вызывать его из основного кода модуля. Фактическим нулевым объектом был MSError :: constructor-> GetFunction().

Благодаря Бен Нордхьюис за то, что указал нам в правильном направлении.

Смежные вопросы