Я работаю над обновлением 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();
}