2

以下のコードは OS X で動作しますが、Ubuntu でコンパイルして実行すると、関数を呼び出すときに segfault が発生しbaton->callbackます。最初の方法をPersistent<Function>超えて持続しないようです。Aysnc::Start

この場合、なぜ OS X で動作するのでしょうか? クロスプラットフォームで動作させるにはどうすればよいですか?

間違っている場合callback、呼び出し元を作成するにはどうすればよい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("Work\n");
}

void Async::AfterWork(uv_work_t *req) {
  printf("AfterWork\n");
  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);
    }
}
4

1 に答える 1

2

私は に精通していませんlibuvが、 の定義を考えると、渡された が に渡されたものと同じであるBatonと仮定すると、ステートメントは実際に構造を削除し、そこからフィールドを読み取ろうとします。の最後に削除して追加してみます。uv_work_t*AfterWork()uv_queue_work()delete reqBatoncallbackdelete reqdelete batonAfterWork()

于 2013-03-20T23:27:27.437 に答える