Skip to content

Instantly share code, notes, and snippets.

@hiroosak
Created July 28, 2014 21:38
Show Gist options
  • Save hiroosak/1be1ade683f22dcb4e1d to your computer and use it in GitHub Desktop.
Save hiroosak/1be1ade683f22dcb4e1d to your computer and use it in GitHub Desktop.
node-gypを使ってnative addonを作成する (2) - 非同期関数をとりあえず作ってみる ref: http://qiita.com/taizo/items/44bf02878f5fc0842703
#include <node.h>
#include <v8.h>
using namespace v8;
typedef struct asyncData {
Persistent<Function> callback;
const char *result;
} AsyncData;
void AsyncWork(uv_work_t *req) {
AsyncData *asyncData = (AsyncData *)req->data;
asyncData->result = "Hello World!";
}
void AsyncAfter(uv_work_t *req) {
HandleScope scope;
AsyncData *asyncData = (AsyncData *)req->data;
Handle<Value> argv[] = {
Null(),
String::New(asyncData->result)
};
// surround in a try/catch for safety
TryCatch try_catch;
// execute the callback function
asyncData->callback->Call(Context::GetCurrent()->Global(), 2, argv);
if (try_catch.HasCaught()) {
node::FatalException(try_catch);
}
delete asyncData;
delete req;
}
Handle<Value> Async(const Arguments& args) {
HandleScope scope;
if (args.Length() < 1) {
ThrowException(Exception::TypeError(String::New("1 arguments expected")));
return scope.Close(Undefined());
}
if (!args[0]->IsFunction()) {
ThrowException(Exception::TypeError(String::New("Wrong arguments")));
return scope.Close(Undefined());
}
Local<Function> callback = Local<Function>::Cast(args[0]);
uv_loop_t *loop = uv_default_loop();
uv_work_t *req = new uv_work_t;
AsyncData *asyncData = new AsyncData;
asyncData->callback = Persistent<Function>::New(callback);
req->data = asyncData;
uv_queue_work(
loop,
req,
AsyncWork,
(uv_after_work_cb)AsyncAfter
);
return scope.Close(Undefined());
}
void init(Handle<Object> exports) {
exports->Set(String::NewSymbol("async"),
FunctionTemplate::New(Async)->GetFunction());
}
NODE_MODULE(addon, init)
var addon = require('./build/Release/addon');
addon.async(function(err, res) {
console.log('err', err); // null
console.log('res', res); // Hello World
});
addon.async(3); // TypeError: Wrong arguments
{
"targets": [{
"target_name": "addon",
"sources": [
"async.cc"
]
}]
}
uv_loop_t *loop = uv_default_loop();
uv_work_t *req = new uv_work_t;
AsyncData *asyncData = new AsyncData;
asyncData->callback = Persistent<Function>::New(callback);
req->data = asyncData; // 引き回すデータを入れる
uv_queue_work(
loop,
req,
AsyncWork, // 実際の処理
(uv_after_work_cb)AsyncAfter // 実行後の処理
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment