编译语句:
node-gyp rebuild --target=2.0.5 --arch=x64 --dist-url=https://atom.io/download/electron --msvs_version=2015
依赖可以在 %USERPROFILE%\.node-gyp
目录下查找。
比如:%USERPROFILE%\.node-gyp\iojs-2.0.5\deps
src/node_demo_js.h
#ifndef __NODE_DEMO_JS_H__
#define __NODE_DEMO_JS_H__
#include "nan.h"
class NodeDemoJs : public Nan::ObjectWrap {
public:
static void Init(v8::Local<v8::Object> exports);
private:
explicit NodeDemoJs(std::string member, int status = 0);
~NodeDemoJs();
static void New(const Nan::FunctionCallbackInfo<v8::Value>& info);
static void GetStatus(const Nan::FunctionCallbackInfo<v8::Value>& info);
static void AppInit(const Nan::FunctionCallbackInfo<v8::Value>& info);
static void AppRun(const Nan::FunctionCallbackInfo<v8::Value>& info);
static void AppCommand(const Nan::FunctionCallbackInfo<v8::Value>& info);
static Nan::Persistent<v8::Function> constructor;
void TestFunc1(std::string & parmas);
void TestFunc2(int &status);
std::string m_demo_member;
int m_status;
};
#endif // __NODE_DEMO_JS_H__
src/node_demo_js.cpp
#include "node_demo_js.h"
#include "v8.h"
#include "node.h"
#include <thread>
#include <iostream>
#include <string>
#define EXPORT_OBJECT_NAME "NodeDemoJs"
#define EXPORT_INF_GETSTATUS "GetStatus"
#define EXPORT_INF_APPINIT "AppInit"
#define EXPORT_INF_APPRUN "AppRun"
#define EXPORT_INF_APPCOMMAND "AppCommand"
Nan::Persistent<v8::Function> NodeDemoJs::constructor;
NodeDemoJs::NodeDemoJs(std::string name, int status)
:m_demo_member(name), m_status(0) {
}
NodeDemoJs::~NodeDemoJs() {
}
void NodeDemoJs::Init(v8::Local<v8::Object> exports) {
v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
tpl->SetClassName(Nan::New(EXPORT_OBJECT_NAME).ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1);
Nan::SetPrototypeMethod(tpl, EXPORT_INF_GETSTATUS, GetStatus);
Nan::SetPrototypeMethod(tpl, EXPORT_INF_APPINIT, AppInit);
Nan::SetPrototypeMethod(tpl, EXPORT_INF_APPRUN, AppRun);
Nan::SetPrototypeMethod(tpl, EXPORT_INF_APPCOMMAND, AppCommand);
constructor.Reset(tpl->GetFunction());
exports->Set(Nan::New(EXPORT_OBJECT_NAME).ToLocalChecked(), tpl->GetFunction());
}
void NodeDemoJs::New(const Nan::FunctionCallbackInfo<v8::Value>& info) {
if (info.IsConstructCall()) {
std::string name("");
if (!info[0]->IsUndefined()) {
v8::String::Utf8Value params1(info[0]->ToString());
name = std::string(*params1);
}
if (name.length() == 0) {
NodeDemoJs* obj = ObjectWrap::Unwrap<NodeDemoJs>(info.Holder());
obj->m_status = -99;
obj->Wrap(info.This());
info.GetReturnValue().Set(info.This());
std::cout << "NodeDemoJs New error: name is null. status: " << obj->m_status << std::endl;
return;
}
int status = 0;
if (!info[1]->IsUndefined()) {
status = info[1]->Int32Value();
}
NodeDemoJs* obj = new NodeDemoJs(name, status);
obj->m_status = 0;
obj->Wrap(info.This());
info.GetReturnValue().Set(info.This());
std::cout << obj->m_demo_member << ": NodeDemoJs New Success.status:" << obj->m_status << std::endl;
}
else {
const int argc = 1;
v8::Local<v8::Value> argv[argc] = { info[0] };
v8::Local<v8::Function> cons = Nan::New<v8::Function>(constructor);
info.GetReturnValue().Set(Nan::NewInstance(cons, argc, argv).ToLocalChecked());
std::cout << ": NodeDemoJs ReNew Success.status: nvl" << std::endl;
}
}
void NodeDemoJs::GetStatus(const Nan::FunctionCallbackInfo<v8::Value>& info) {
NodeDemoJs* obj = ObjectWrap::Unwrap<NodeDemoJs>(info.Holder());
info.GetReturnValue().Set(Nan::New(obj->m_status));
}
void NodeDemoJs::AppInit(const Nan::FunctionCallbackInfo<v8::Value>& info) {
NodeDemoJs* obj = ObjectWrap::Unwrap<NodeDemoJs>(info.Holder());
std::string name = obj->m_demo_member;
int status = 2;
obj->TestFunc2(status);
std::cout << "TestFunc2(2) " << status << std::endl;
obj->m_status = 1;
info.GetReturnValue().Set(Nan::New(obj->m_status));
std::cout << obj->m_demo_member << ": AppInit Success. status:" << obj->m_status << std::endl;
}
void NodeDemoJs::AppRun(const Nan::FunctionCallbackInfo<v8::Value>& info) {
NodeDemoJs* obj = ObjectWrap::Unwrap<NodeDemoJs>(info.Holder());
obj->m_status = 2;
info.GetReturnValue().Set(Nan::New(obj->m_status));
std::cout << obj->m_demo_member << ": AppRun Success. status:" << obj->m_status << std::endl;
}
void NodeDemoJs::AppCommand(const Nan::FunctionCallbackInfo<v8::Value>& info) {
NodeDemoJs* obj = ObjectWrap::Unwrap<NodeDemoJs>(info.Holder());
v8::Isolate * isolate = info.GetIsolate();
v8::Local<v8::String> value = info[0]->IsUndefined() ? v8::String::NewFromUtf8(isolate, std::to_string(3).c_str()) : info[0]->ToString();
std::string params(*v8::String::Utf8Value(value));
obj->m_status = 3;
std::cout << params << obj->m_status << std::endl;
info.GetReturnValue().Set(Nan::New(obj->m_status));
}
void NodeDemoJs::TestFunc1(std::string & parmas)
{
std::cout << "NodeDemoJs::TestFunc1(" << parmas << ")" << std::endl;
}
void NodeDemoJs::TestFunc2(int &status)
{
status *= 2;
std::cout << "ststus: " << status << std::endl;
}
src/node_demo_js_main.cpp
#include "node_demo_js.h"
void InitAll(v8::Local<v8::Object> exports) {
NodeDemoJs::Init(exports);
}
NODE_MODULE(NODE_GYP_MODULE_NAME, InitAll)
binding.gyp
{
"targets": [
{
# 注意 target_name 的名字不能有-号
"target_name": "node_demo_js",
#"type": "shared_library",
"sources": [ "src/node_demo_js.cpp",
"src/node_demo_js.h",
"src/node_demo_js_main.cpp"
],
'msbuild_toolset': 'v140',
'include_dirs': [
'../electron-deps/iojs-2.0.5/src',
'../electron-deps/iojs-2.0.5/deps/uv/include',
'../electron-deps/iojs-2.0.5/deps/nan',
'../electron-deps/iojs-2.0.5/deps/v8/include'
],
'link_settings': {
'conditions': [
['OS=="win" and target_arch=="ia32"', {
'libraries': [ '-l../../electron-deps/iojs-2.0.5/ia32/iojs' ],
}],
['OS=="win" and target_arch=="x64"', {
'libraries': [ '-l../../electron-deps/iojs-2.0.5/x64/iojs' ],
}],
],
},
'conditions': [
# 配合调试和发布,设置c++预编译宏
['target_arch=="x64"', {
'defines': [
'WIN32',
'_ARCH=64',
],
}],
['target_arch=="ia32"', {
'defines': [
'WIN32',
'_ARCH=32',
],
}],
],
# msvs编译后处理
'msvs_postbuild': r'copy /y "$(OutDir)$(TargetName)$(TargetExt)" "$(OutDir)..\..\bin\<(target_arch)\$(TargetName)$(TargetExt)"',
},
],
}