Nižšie uvedený kód funguje v OS X, ale keď ho skompilujem a spustím v Ubuntu, pri volaní baton->callback
Funkcie. Zdá sa, že Persistent<Function>
nepretrváva mimo pôvodného stavu Aysnc::Start
metóda.
Ak je to tak, prečo to funguje na OS X? Čo môžem urobiť, aby to fungovalo na viacerých platformách?
Ak to robím zle, čo musím urobiť, aby som si vytvoril callback
volať z AfterWork
?
// Async.h
#include <v8.h>
#include <node.h>
#include <string>
using namespace node;
using namespace v8;
class Async : public ObjectWrap {
public:
static Persistent<Function> constructor_template;
static void Initialize(Handle<v8::Object> target);
protected:
Async() {}
~Async() {}
static Handle<Value> Start(const Arguments& args);
static void Work(uv_work_t* req);
static void AfterWork(uv_work_t* req);
private:
struct Baton {
uv_work_t request;
Persistent<Function> callback;
};
};
// Async.cc
Handle<Value> Async::Start(const Arguments& args) {
HandleScope scope;
if(args.Length() == 0 || !args[0]->IsFunction()) {
return ThrowException(Exception::Error(String::New("Callback is required and must be a Function.")));
}
Baton *baton = new Baton();
baton->request.data = baton;
baton->callback = Persistent<Function>::New(Handle<Function>::Cast(args[0]));
uv_queue_work(uv_default_loop(), &baton->request, Work, (uv_after_work_cb)AfterWork);
return Undefined();
}
void Async::Work(uv_work_t *req) {
printf("Workn");
}
void Async::AfterWork(uv_work_t *req) {
printf("AfterWorkn");
HandleScope scope;
Baton *baton = static_cast<Baton *>(req->data);
delete req;
Local<Value> argv[1] = {
Local<Value>::New(Null());
};
TryCatch try_catch;
// Segfault occurs here
baton->callback->Call(Context::GetCurrent()->Global(), 1, argv);
if (try_catch.HasCaught()) {
node::FatalException(try_catch);
}
}
odpovede:
2 pre odpoveď č. 1Nie som oboznámený libuv
, ale podľa vašej definície Baton
a za predpokladu, že uv_work_t*
prešiel do AfterWork()
je rovnaká ako tá, do ktorej prešiel uv_queue_work()
, vaše delete req
vyhlásenie skutočne vymaže vaše Baton
štruktúra, z ktorej sa potom pokúsite prečítať callback
lúka. Skúsim odstrániť delete req
a pridanie delete baton
na samom konci mesta AfterWork()
.