写c++扩展的时候,怎么样让node-gyp找到需要的头文件 写c++扩展的时候,怎么样让node-gyp找到需要的头文件

\u5199c++\u6269\u5c55\u7684\u65f6\u5019\uff0c\u600e\u4e48\u6837\u8ba9node-gyp\u627e\u5230\u9700\u8981\u7684\u5934\u6587\u4ef6

\u6ca1\u88c5node-gyp\u5427\u3002
\u7528npm\u53ef\u4ee5\u88c5\u3002
\u53e6\u5916\uff0c\u5728win8\u88c5node-gyp\u4f60\u9700\u8981\u5148\u6709python2.7\u548cvisual studio C++ 2012

\u4e00\u3001\u7f16\u5199Node.js\u539f\u751f\u6269\u5c55

Node.js\u662f\u4e00\u4e2a\u5f3a\u5927\u7684\u5e73\u53f0\uff0c\u7406\u60f3\u72b6\u6001\u4e0b\u4e00\u5207\u90fd\u90fd\u53ef\u4ee5\u7528javascript\u5199\u6210\u3002\u7136\u800c\uff0c\u4f60\u53ef\u80fd\u8fd8\u4f1a\u7528\u5230\u8bb8\u591a\u9057\u7559\u7684\u5e93\u548c\u7cfb\u7edf\uff0c\u8fd9\u6837\u7684\u8bdd\u4f7f\u7528c++\u7f16\u5199Node.JS\u6269\u5c55\u4f1a\u662f\u4e00\u4e2a\u4e0d\u9519\u7684\u6ce8\u610f\u3002

\u4ee5\u4e0b\u6240\u6709\u4f8b\u5b50\u7684\u6e90\u4ee3\u7801\u53ef\u5728node\u6269\u5c55\u793a\u4f8b\u4e2d\u627e\u5230 \u3002

\u7f16\u5199Node.js C + +\u6269\u5c55\u5f88\u5927\u7a0b\u5ea6\u4e0a\u5c31\u50cf\u662f\u5199V8\u7684\u6269\u5c55\uff1b Node.js\u589e\u52a0\u4e86\u4e00\u4e9b\u63a5\u53e3\uff0c\u4f46\u5927\u90e8\u5206\u65f6\u95f4\u4f60\u90fd\u662f\u5728\u4f7f\u539f\u59cb\u7684V8\u6570\u636e\u7c7b\u578b\u548c\u65b9\u6cd5\uff0c\u4e3a\u4e86\u7406\u89e3\u4ee5\u4e0b\u7684\u4ee3\u7801\uff0c\u4f60\u5fc5\u987b\u9996\u5148\u9605\u8bfbV8\u5f15\u64ce\u5d4c\u5165\u6307\u5357\u3002

Javascript\u7248\u672c\u7684Hello World

\u5728\u8bb2\u89e3C++\u7248\u672c\u7684\u4f8b\u5b50\u4e4b\u524d\uff0c\u5148\u8ba9\u6211\u4eec\u6765\u770b\u770b\u5728Node.js\u4e2d\u7528Javascript\u7f16\u5199\u7684\u7b49\u4ef7\u6a21\u5757\u662f\u4ec0\u4e48\u6837\u5b50\u3002\u8fd9\u662f\u4e00\u4e2a\u6700\u7b80\u5355\u7684Hello World\uff0c\u4e5f\u4e0d\u662f\u901a\u8fc7HTTP\uff0c\u4f46\u5b83\u5c55\u793a\u4e86node\u6a21\u5757\u7684\u7ed3\u6784\uff0c\u800c\u5176\u63a5\u53e3\u4e5f\u548c\u5927\u591a\u6570C++\u6269\u5c55\u8981\u63d0\u4f9b\u7684\u63a5\u53e3\u5dee\u4e0d\u591a\uff1a

HelloWorldJs = function() {

this.m_count = 0;

};

HelloWorldJs.prototype.hello = function()

{

this.m_count++;

return \u201cHello World\u201d;

};

exports.HelloWorldJs = HelloWorldJs;

\u6b63\u5982\u4f60\u6240\u770b\u5230\u7684\uff0c\u5b83\u4f7f\u7528prototype\u4e3aHelloWorldJs\u7c7b\u521b\u5efa\u4e86\u4e00\u4e2a\u65b0\u7684\u65b9\u6cd5\u3002\u8bf7\u6ce8\u610f\uff0c\u4e0a\u8ff0\u4ee3\u7801\u901a\u8fc7\u5c06HelloWorldJS\u6dfb\u52a0\u5230exports\u53d8\u91cf\u6765\u66b4\u9732\u6784\u9020\u51fd\u6570\u3002

\u8981\u5728\u5176\u4ed6\u5730\u65b9\u4f7f\u7528\u8be5\u6a21\u5757\uff0c\u8bf7\u4f7f\u7528\u5982\u4e0b\u4ee3\u7801\uff1a

var helloworld = require(\u2018helloworld_js\u2019);

var hi = new helloworld.HelloWorldJs();

console.log(hi.hello()); // prints \u201cHello World\u201d to stdout

C++\u7248\u672c\u7684Hello World

\u8981\u5f00\u59cb\u7f16\u5199C++\u6269\u5c55\uff0c\u9996\u5148\u8981\u80fd\u591f\u7f16\u8bd1Node.js\uff08\u8bf7\u6ce8\u610f\uff0c\u6211\u4eec\u4f7f\u7528\u7684\u662fNode.js 2.0\u7248\u672c\uff09\u3002\u672c\u6587\u6240\u8bb2\u5185\u5bb9\u5e94\u8be5\u517c\u5bb9\u6240\u6709\u672a\u6765\u76840.2.x\u7248\u672c\u3002\u4e00\u65e6\u7f16\u8bd1\u5b89\u88c5\u5b8cnode\uff0c\u7f16\u8bd1\u6a21\u5757\u5c31\u4e0d\u5728\u9700\u8981\u989d\u5916\u7684\u4e1c\u897f\u4e86\u3002

\u5b8c\u6574\u7684\u6e90\u4ee3\u7801\u53ef\u4ee5\u5728\u8fd9\u91cc\u627e\u5230 \u3002\u5728\u4f7f\u7528Node.js\u6216V8\u4e4b\u524d\uff0c\u6211\u4eec\u9700\u8981\u5305\u62ec\u76f8\u5173\u7684\u5934\u6587\u4ef6\uff1a

#include

#include

using namespace node;

using namespace v8;

\u5728\u672c\u4f8b\u5b50\u4e2d\u6211\u76f4\u63a5\u4f7f\u7528\u4e86V8\u548cnode\u7684\u547d\u540d\u7a7a\u95f4\uff0c\u4f7f\u4ee3\u7801\u66f4\u6613\u4e8e\u9605\u8bfb\u3002\u867d\u7136\u8fd9\u79cd\u7528\u6cd5\u548c\u8c37\u6b4c\u7684\u81ea\u5df1\u7684C++\u7f16\u7a0b\u98ce\u683c\u6307\u5357\u76f8\u6096\uff0c\u4f46\u7531\u4e8e\u4f60\u9700\u8981\u4e0d\u505c\u7684\u4f7f\u7528V8\u5b9a\u4e49\u7684\u7c7b\u578b\uff0c\u6240\u4ee5\u76ee\u524d\u4e3a\u6b62\u7684\u5927\u591a\u6570node\u7684\u6269\u5c55\u4ecd\u7136\u4f7f\u7528\u4e86V8\u7684\u547d\u540d\u7a7a\u95f4\u3002

\u63a5\u4e0b\u6765\uff0c\u58f0\u660eHelloWorld\u7c7b\u3002\u5b83\u7ee7\u627f\u81eanode::ObjectWrap\u7c7b \uff0c\u8fd9\u4e2a\u7c7b\u63d0\u4f9b\u4e86\u51e0\u4e2a\u5982\u5f15\u7528\u8ba1\u6570\u3001\u5728V8\u5185\u90e8\u4f20\u9012contex\u7b49\u7684\u5b9e\u7528\u529f\u80fd\u3002\u4e00\u822c\u6765\u8bf4\uff0c\u6240\u6709\u5bf9\u8c61\u5e94\u8be5\u7ee7\u627fObjectWrap\uff1a

class HelloWorld: ObjectWrap

{

private:

int m_count;

public:

\u58f0\u660e\u7c7b\u4e4b\u540e\uff0c\u6211\u4eec\u5b9a\u4e49\u4e86\u4e00\u4e2a\u9759\u6001\u6210\u5458\u51fd\u6570\uff0c\u7528\u6765\u521d\u59cb\u5316\u5bf9\u8c61\u5e76\u5c06\u5176\u5bfc\u5165Node.js\u63d0\u4f9b\u7684target\u5bf9\u8c61\u4e2d\u3002\u8bbe\u4e2a\u51fd\u6570\u57fa\u672c\u4e0a\u662f\u544a\u8bc9Node.js\u548cV8\u4f60\u7684\u7c7b\u662f\u5982\u4f55\u521b\u5efa\u7684\uff0c\u548c\u5b83\u5c06\u5305\u542b\u4ec0\u4e48\u65b9\u6cd5\uff1a

static Persistent s_ct;

static void Init(Handle target)

{

HandleScope scope;

Local t = FunctionTemplate::New(New);

s_ct = Persistent::New(t);

s_ct->InstanceTemplate()->SetInternalFieldCount(1);

s_ct->SetClassName(String::NewSymbol(\u201cHelloWorld\u201d));

NODE_SET_PROTOTYPE_METHOD(s_ct, \u201chello\u201d, Hello);

target->Set(String::NewSymbol(\u201cHelloWorld\u201d),

s_ct->GetFunction());

}

\u5728\u4e0a\u9762\u8fd9\u4e2a\u51fd\u6570\u4e2dtarget\u53c2\u6570\u5c06\u662f\u6a21\u5757\u5bf9\u8c61\uff0c\u5373\u4f60\u7684\u6269\u5c55\u5c06\u8981\u8f7d\u5165\u7684\u5730\u65b9\u3002\uff08\u8bd1\u8457\uff1a\u8fd9\u4e2a\u51fd\u6570\u5c06\u4f60\u7684\u5bf9\u8c61\u53ca\u5176\u65b9\u6cd5\u8fde\u63a5\u5230
\u8fd9\u4e2a\u6a21\u5757\u5bf9\u8c61\uff0c\u4ee5\u4fbf\u5916\u754c\u53ef\u4ee5\u8bbf\u95ee\uff09\u9996\u5148\u6211\u4eec\u4e3aNew\u65b9\u6cd5\u521b\u5efa\u4e00\u4e2aFunctionTemplate\uff0c\u5c06\u4e8e\u7a0d\u540e\u89e3\u91ca\u3002\u6211\u4eec\u8fd8\u4e3a\u8be5\u5bf9\u8c61\u6dfb\u52a0\u4e00\u4e2a\u5185\u90e8\u5b57\u6bb5\uff0c\u5e76\u547d
\u540d\u4e3aHelloWorld\u3002\u7136\u540e\u4f7f\u7528NODE_SET_PROTOTYPE_METHOD\u5b8f\u5c06hello\u65b9\u6cd5\u7ed1\u5b9a\u5230\u8be5\u5bf9\u8c61\u3002\u6700\u540e\uff0c\u4e00\u65e6\u6211\u4eec\u5efa\u7acb\u597d\u8fd9\u4e2a\u51fd\u6570\u6a21\u677f\u540e\uff0c\u5c06\u4ed6\u5206\u914d\u7ed9target\u5bf9\u8c61\u7684HelloWorld\u5c5e\u6027\uff0c\u5c06\u7c7b\u66b4\u9732\u7ed9\u7528\u6237\u3002

\u63a5\u4e0b\u6765\u7684\u90e8\u5206\u662f\u4e00\u4e2a\u6807\u51c6\u7684C++\u6784\u9020\u51fd\u6570\uff1a

HelloWorld() :

m_count(0)

{

}

~HelloWorld()

{

}

\u63a5\u4e0b\u6765\uff0c\u5728::New \u65b9\u6cd5\u4e2dV8\u5f15\u64ce\u5c06\u8c03\u7528\u8fd9\u4e2a\u7b80\u5355\u7684C++\u6784\u9020\u51fd\u6570\uff1a

static Handle New(const Arguments& args)

{

HandleScope scope;

HelloWorld* hw = new HelloWorld();

hw->Wrap(args.This());

return args.This();

}

\u6b64\u6bb5\u4ee3\u7801\u76f8\u5f53\u4e8e\u4e0a\u9762Javascript\u4ee3\u7801\u4e2d\u4f7f\u7528\u7684\u6784\u9020\u51fd\u6570\u3002\u5b83\u8c03\u7528new HelloWorld
\u521b\u9020\u4e86\u4e00\u4e2a\u666e\u901a\u7684C++\u5bf9\u8c61\uff0c\u7136\u540e\u8c03\u7528\u4eceObjectWrap\u7ee7\u627f\u7684Wrap\u65b9\u6cd5\uff0c
\u5b83\u5c06\u4e00\u4e2aC++HelloWorld\u7c7b\u7684\u5f15\u7528\u4fdd\u5b58\u5230args.This()\u7684\u503c\u4e2d\u3002\u5728\u5305\u88c5\u5b8c\u6210\u540e\u8fd4\u56deargs.This()\uff0c\u6574\u4e2a\u51fd\u6570\u7684\u884c\u4e3a\u548c
javascript\u4e2d\u7684new\u8fd0\u7b97\u7b26\u7c7b\u4f3c\uff0c\u8fd4\u56dethis\u6307\u5411\u7684\u5bf9\u8c61\u3002

\u73b0\u5728\u6211\u4eec\u5df2\u7ecf\u5efa\u7acb\u4e86\u5bf9\u8c61\uff0c\u4e0b\u9762\u4ecb\u7ecd\u5728Init\u51fd\u6570\u4e2d\u88ab\u7ed1\u5b9a\u5230hello\u7684\u51fd\u6570\uff1a

static Handle Hello(const Arguments& args)

{

HandleScope scope;

HelloWorld* hw = ObjectWrap::Unwrap(args.This());

hw->m_count++;

Local result = String::New(\u201cHello World\u201d);

return scope.Close(result);

}

\u51fd\u6570\u4e2d\u9996\u5148\u4f7f\u7528ObjectWrap\u6a21\u677f\u7684\u65b9\u6cd5\u63d0\u53d6\u51fa\u6307\u5411HelloWorld\u7c7b\u7684\u6307\u9488\uff0c\u7136\u540e\u548cjavascript\u7248\u672c\u7684HelloWorld\u4e00\u6837\u9012\u589e\u8ba1\u6570\u5668\u3002\u6211\u4eec\u65b0\u5efa\u4e00\u4e2a\u5185\u5bb9\u4e3a\u201cHelloWorld\u201d\u7684v8\u5b57\u7b26\u4e32\u5bf9\u8c61\uff0c\u7136\u540e\u5728\u5173\u95ed\u672c\u5730\u4f5c\u7528\u57df\u7684\u65f6\u5019\u8fd4\u56de\u8fd9\u4e2a\u5b57\u7b26\u4e32\u3002

\u4e0a\u9762\u7684\u4ee3\u7801\u5b9e\u9645\u4e0a\u53ea\u662f\u9488\u5bf9v8\u7684\u63a5\u53e3\uff0c\u6700\u7ec8\u6211\u4eec\u8fd8\u9700\u8981\u8ba9Node.js\u77e5\u9053\u5982\u4f55\u52a8\u6001\u52a0\u8f7d\u6211\u4eec\u7684\u4ee3\u7801\u3002\u4e3a\u4e86\u4f7fNode.js\u7684\u6269\u5c55\u53ef\u4ee5\u5728\u6267\u884c\u65f6\u4ece\u52a8\u6001\u94fe\u63a5\u5e93\u52a0\u8f7d\uff0c\u9700\u8981\u6709\u4e00\u4e2adlsym\u51fd\u6570\u53ef\u4ee5\u8bc6\u522b\u7684\u7b26\u53f7\uff0c\u6240\u4ee5\u6267\u884c\u7f16\u5199\u5982\u4e0b\u4ee3\u7801\uff1a

extern \u201cC\u201d {

static void init (Handle target)

{

HelloWorld::Init(target);

}

NODE_MODULE(helloworld, init);

}

\u7531\u4e8ec++\u7684\u7b26\u53f7\u547d\u540d\u89c4\u5219\uff0c\u6211\u4eec\u4f7f\u7528extern
C\uff0c\u4ee5\u4fbf\u8be5\u7b26\u53f7\u53ef\u4ee5\u88abdysym\u8bc6\u522b\u3002init\u65b9\u6cd5\u662fNode.js\u52a0\u8f7d\u6a21\u5757\u540e\u7b2c\u4e00\u4e2a\u8c03\u7528\u7684\u51fd\u6570\uff0c\u5982\u679c\u4f60\u6709\u591a\u4e2a\u7c7b\u578b\uff0c\u8bf7\u5168\u90e8\u5728\u8fd9\u91cc\u521d\u59cb\u5316\u3002
NODE_MODULE\u5b8f\u7528\u6765\u586b\u5145\u4e00\u4e2a\u7528\u4e8e\u5b58\u50a8\u6a21\u5757\u4fe1\u606f\u7684\u7ed3\u6784\u4f53\uff0c\u5b58\u50a8\u7684\u4fe1\u606f\u5982\u6a21\u5757\u4f7f\u7528\u7684API\u7248\u672c\u3002\u8fd9\u4e9b\u4fe1\u606f\u53ef\u4ee5\u7528\u6765\u9632\u6b62\u672a\u6765\u56e0API\u4e0d\u517c\u5bb9\u5bfc\u81f4\u7684\u5d29
\u6e83\u3002

\u5230\u6b64\uff0c\u6211\u4eec\u5df2\u7ecf\u5b8c\u6210\u4e86\u4e00\u4e2a\u53ef\u7528\u7684C++ NodeJS\u6269\u5c55\u3002

Node.js\u4e5f\u63d0\u4f9b\u4e86\u4e00\u4e2a\u7528\u4e8e\u6784\u5efa\u6a21\u5757\u7684\u7b80\u5355\u5de5\u5177:
node-waf\u9996\u5148\u7f16\u5199\u4e00\u4e2a\u5305\u542b\u6269\u5c55\u7f16\u8bd1\u65b9\u6cd5\u7684wscript\u6587\u4ef6\uff0c\u7136\u540e\u6267\u884cnode-waf configure &&
node-waf build\u5b8c\u6210\u6a21\u5757\u7684\u7f16\u8bd1\u548c\u94fe\u63a5\u5de5\u4f5c\u3002\u5bf9\u4e8e\u8fd9\u4e2ahelloworld\u7684\u4f8b\u5b50\u6765\u8bf4\uff0cwscript\u5185\u5bb9\u5982\u4e0b\uff1a

def set_options(opt):

opt.tool_options(\u201ccompiler_cxx\u201d)

def configure(conf):

conf.check_tool(\u201ccompiler_cxx\u201d)

conf.check_tool(\u201cnode_addon\u201d)

def build(bld):

obj = bld.new_task_gen(\u201ccxx\u201d, \u201cshlib\u201d, \u201cnode_addon\u201d)

obj.cxxflags = [\u201c-g\u201d, \u201c-D_FILE_OFFSET_BITS=64\u201d, \u201c-D_LARGEFILE_SOURCE\u201d, \u201c-Wall\u201d]

obj.target = \u201chelloworld\u201d

obj.source = \u201chelloworld.cc\u201d

\u5f02\u6b65IO\u7684HelloWorld

\u5bf9\u4e8e\u5b9e\u9645\u7684\u5e94\u7528\u6765\u8bf4\uff0cHelloWorld\u7684\u793a\u4f8b\u592a\u8fc7\u7b80\u5355\u4e86\u4e00\u4e9b\uff0cNode.js\u4e3b\u8981\u7684\u4f18\u52bf\u662f\u63d0\u4f9b\u5f02\u6b65IO\u3002
Node.js\u5185\u90e8\u901a\u8fc7libeio\u5c06\u4f1a\u4ea7\u751f\u963b\u585e\u7684\u64cd\u4f5c\u5168\u90fd\u653e\u5165\u7ebf\u7a0b\u6c60\u4e2d\u6267\u884c\u3002\u5982\u679c\u9700\u8981\u548c\u9057\u7559\u7684c\u5e93\u4ea4\u4e92\uff0c\u901a\u5e38\u9700\u8981\u4f7f\u7528\u5f02\u6b65IO\u6765\u4e3ajavascript
\u4ee3\u7801\u63d0\u4f9b\u56de\u8c03\u63a5\u53e3\u3002

\u901a\u5e38\u7684\u6a21\u5f0f\u662f\u63d0\u4f9b\u4e00\u4e2a\u56de\u8c03\uff0c\u5728\u5f02\u6b65\u64cd\u4f5c\u5b8c\u6210\u65f6\u88ab\u8c03\u7528\u2014\u2014\u4f60\u53ef\u4ee5\u5728\u6574\u4e2aNode.js\u7684API\u4e2d\u770b\u5230\u8fd9\u79cd\u6a21\u5f0f\u3002
Node.js\u7684filesystem\u6a21\u5757\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5f88\u597d\u7684\u4f8b\u5b50\uff0c\u5176\u4e2d\u5927\u591a\u6570\u7684\u51fd\u6570\u90fd\u5728\u64cd\u4f5c\u5b8c\u6210\u540e\u901a\u8fc7\u8c03\u7528\u56de\u8c03\u51fd\u6570\u6765\u4f20\u9012\u6570\u636e\u3002\u548c\u8bb8\u591a\u4f20\u7edf\u7684GUI\u6846\u67b6\u4e00
\u6837\uff0cNode.js\u53ea\u5728\u4e3b\u7ebf\u7a0b\u4e2d\u6267\u884cJavaScript\uff0c\u56e0\u6b64\u4e3b\u7ebf\u7a0b\u4ee5\u5916\u7684\u4efb\u4f55\u64cd\u4f5c\u90fd\u4e0d\u5e94\u8be5\u76f4\u63a5\u548cV8\u6216Javascript\u4ea4\u4e92\u3002

\u540c\u6837helloworld_eio.cc\u6e90\u4ee3\u7801\u5728GitHub\u4e0a\u3002\u6211\u53ea\u5f3a\u8c03\u548c\u539f\u6765HelloWorld\u4e4b\u95f4\u7684\u5dee\u5f02\uff0c\u5176\u4e2d\u5927\u90e8\u5206\u4ee3\u7801\u4fdd\u6301\u4e0d\u53d8\uff0c\u53d8\u5316\u96c6\u4e2d\u5728Hello\u65b9\u6cd5\u4e2d\uff1a

static Handle Hello(const Arguments& args)

{

HandleScope scope;

REQ_FUN_ARG(0, cb);

HelloWorldEio* hw = ObjectWrap::Unwrap(args.This());

\u5728Hello\u51fd\u6570\u7684\u5165\u53e3\u5904 \uff0c\u6211\u4eec\u4f7f\u7528\u5b8f\u4ece\u53c2\u6570\u5217\u8868\u7684\u7b2c\u4e00\u4e2a\u4f4d\u7f6e\u83b7\u53d6\u56de\u8c03\u51fd\u6570\uff0c\u5728\u4e0b\u4e00\u8282\u4e2d\u5c06\u8be6\u7ec6\u4ecb\u7ecd\u3002\u7136\u540e\uff0c\u6211\u4eec\u4f7f\u7528\u76f8\u540c\u7684Unwarp\u65b9\u6cd5\u63d0\u53d6\u6307\u5411\u7c7b\u5bf9\u8c61\u7684\u6307\u9488\u3002

hello_baton_t *baton = new hello_baton_t();

baton->hw = hw;

baton->increment_by = 2;

baton->sleep_for = 1;

baton->cb = Persistent::New(cb);

\u8fd9\u91cc\u6211\u4eec\u521b\u5efa\u4e00\u4e2abaton\u7ed3\u6784\uff0c\u5e76\u5c06\u5404\u79cd\u53c2\u6570\u4fdd\u5b58\u5728\u91cc\u9762\u3002\u8bf7\u6ce8\u610f\uff0c\u6211\u4eec\u4e3a\u56de\u8c03\u51fd\u6570\u521b\u5efa\u4e86\u4e00\u4e2a\u6c38\u4e45\u5f15\u7528\uff0c\u56e0\u4e3a\u6211\u4eec\u60f3\u8981\u5728\u8d85\u51fa\u5f53\u524d\u51fd\u6570\u4f5c\u7528\u57df\u7684\u5730\u65b9\u4f7f\u7528\u5b83\u3002\u5982\u679c\u4e0d\u8fd9\u4e48\u505a\uff0c\u5728\u672c\u51fd\u6570\u7ed3\u675f\u540e\u5c06\u65e0\u6cd5\u518d\u8c03\u7528\u56de\u8c03\u51fd\u6570\u3002

hw->Ref();

eio_custom(EIO_Hello, EIO_PRI_DEFAULT, EIO_AfterHello, baton);

ev_ref(EV_DEFAULT_UC);

return Undefined();

}

\u5982\u4e0b\u4ee3\u7801\u662f\u771f\u6b63\u7684\u91cd\u70b9\u3002\u9996\u5148\uff0c\u6211\u4eec\u589e\u52a0HelloWorld\u5bf9\u8c61\u7684\u5f15\u7528\u8ba1\u6570\uff0c\u8fd9\u6837\u5728\u5176\u4ed6\u7ebf\u7a0b\u6267\u884c\u7684\u65f6\u5019\u4ed6\u5c31\u4e0d\u4f1a\u88ab\u56de\u6536\u3002
\u51fd\u6570eio_custom\u63a5\u53d7\u4e24\u4e2a\u51fd\u6570\u6307\u9488\u4f5c\u4e3a\u53c2\u6570\u3002EIO_Hello\u51fd\u6570\u5c06\u5728\u7ebf\u7a0b\u6c60\u4e2d\u6267\u884c\uff0c\u7136\u540eEIO_AfterHello\u51fd\u6570\u5c06\u56de\u5230\u5728\u201c\u4e3b\u7ebf\u7a0b\u201d
\u4e2d\u6267\u884c\u3002\u6211\u4eec\u7684baton\u7ed3\u6784\u4e5f\u88ab\u4f20\u9012\u8fdb\u5404\u51fd\u6570\uff0c\u8fd9\u4e9b\u51fd\u6570\u53ef\u4ee5\u4f7f\u7528baton\u7ed3\u6784\u4e2d\u7684\u6570\u636e\u5b8c\u6210\u76f8\u5173\u7684\u64cd\u4f5c\u3002\u540c\u65f6\uff0c\u6211\u4eec\u4e5f\u589e\u52a0event
loop\u7684\u5f15\u7528\u3002\u8fd9\u5f88\u91cd\u8981\uff0c\u56e0\u4e3a\u5982\u679cevent
loop\u65e0\u4e8b\u53ef\u505a\uff0cNode.js\u5c31\u4f1a\u9000\u51fa\u3002\u6700\u7ec8\uff0c\u51fd\u6570\u8fd4\u56deUndefined\uff0c\u56e0\u4e3a\u771f\u6b63\u7684\u5de5\u4f5c\u5c06\u5728\u5176\u4ed6\u7ebf\u7a0b\u4e2d\u5b8c\u6210\u3002

static int EIO_Hello(eio_req *req)

{

hello_baton_t *baton = static_cast(req->data);

sleep(baton->sleep_for);

baton->hw->m_count += baton->increment_by;

return 0;

}

\u8fd9\u4e2a\u56de\u8c03\u51fd\u6570\u5c06\u5728libeio\u7ba1\u7406\u7684\u7ebf\u7a0b\u4e2d\u6267\u884c\u3002\u9996\u5148\uff0c\u89e3\u6790\u51fabaton\u7ed3\u6784\uff0c\u8fd9\u6837\u53ef\u4ee5\u8bbf\u95ee\u4e4b\u524d\u8bbe\u7f6e\u7684\u5404\u79cd\u53c2\u6570\u3002\u7136\u540e
sheep
baton->sleep_for\u79d2\uff0c\u8fd9\u4e48\u505a\u662f\u5b89\u5168\u7684\uff0c\u56e0\u4e3a\u8fd9\u4e2a\u51fd\u6570\u8fd0\u884c\u5728\u72ec\u7acb\u7684\u7ebf\u7a0b\u4e2d\u5e76\u4e0d\u4f1a\u963b\u585e\u4e3b\u7ebf\u7a0b\u4e2djavascript\u7684\u6267\u884c\u3002\u7136\u540e\u6211\u4eec\u7684
\u589e\u8ba1\u6570\u5668\uff0c\u5728\u5b9e\u9645\u7684\u7cfb\u7edf\u4e2d\uff0c\u8fd9\u4e9b\u64cd\u4f5c\u901a\u5e38\u9700\u8981\u4f7f\u7528Lock/Mutex\u8fdb\u884c\u540c\u6b65\u3002

\u5f53\u4e0a\u8ff0\u65b9\u6cd5\u8fd4\u56de\u540e\uff0clibeio\u5c06\u4f1a\u901a\u77e5\u4e3b\u7ebf\u7a0b\u5b83\u9700\u8981\u5728\u4e3b\u7ebf\u6210\u4e0a\u6267\u884c\u4ee3\u7801\uff0c\u6b64\u65f6EIO_AfterHello\u5c06\u4f1a\u88ab\u8c03\u7528\u3002

static int EIO_AfterHello(eio_req *req)

{

HandleScope scope;

hello_baton_t *baton = static_cast(req->data);

ev_unref(EV_DEFAULT_UC);

baton->hw->Unref();

\u8fdb\u5ea6\u6b64\u51fd\u6570\u65f6\uff0c\u6211\u4eec\u63d0\u53d6\u51fabaton\u7ed3\u6784\uff0c\u5220\u9664\u4e8b\u4ef6\u5faa\u73af\u7684\u5f15\u7528\uff0c\u5e76\u51cf\u5c11HelloWorld\u5bf9\u8c61\u7684\u5f15\u7528\u3002

Local argv[1];

argv[0] = String::New(\u201cHello World\u201d);

TryCatch try_catch;

baton->cb->Call(Context::GetCurrent()->Global(), 1, argv);

if (try_catch.HasCaught()) {

FatalException(try_catch);

}

\u65b0\u5efa\u8981\u4f20\u9012\u7ed9\u56de\u8c03\u51fd\u6570\u7684\u5b57\u7b26\u4e32\u53c2\u6570\uff0c\u5e76\u653e\u5165\u5b57\u7b26\u4e32\u6570\u7ec4\u4e2d\u3002\u7136\u540e\u6211\u4eec\u8c03\u7528\u56de\u8c03\u4f20\u9012\u4e00\u4e2a\u53c2\u6570\uff0c\u5e76\u68c0\u6d4b\u53ef\u80fd\u629b\u51fa\u7684\u5f02\u5e38\u3002

baton->cb.Dispose();

delete baton;

return 0;

}

\u5728\u6267\u884c\u8fc7\u56de\u8c03\u4e4b\u540e\uff0c\u5e94\u8be5\u9500\u6bc1\u6301\u4e45\u5f15\u7528\uff0c\u7136\u540e\u5220\u9664\u4e4b\u524d\u521b\u5efa\u7684baton\u7ed3\u6784\u3002

\u6700\u540e\uff0c\u4f60\u53ef\u4ee5\u4f7f\u7528\u5982\u4e0b\u5f62\u5f0f\u5728Javascript\u4e2d\u4f7f\u7528\u8be5\u6a21\u5757\uff1a

var helloeio = require(\u2018./helloworld_eio\u2019);

hi = new helloeio.HelloWorldEio();

hi.hello(function(data){

console.log(data);

});

\u53c2\u6570\u4f20\u9012\u4e0e\u89e3\u6790

\u9664\u4e86HelloWorld\u4e4b\u5916\uff0c\u4f60\u8fd8\u9700\u8981\u7406\u89e3\u6700\u540e\u4e00\u4e2a\u95ee\u9898\uff1a\u53c2\u6570\u7684\u5904\u7406\u3002\u5728helloWorld EIO\u4f8b\u5b50\u4e2d\uff0c\u6211\u4eec\u4f7f\u7528\u4e00\u4e2aREQ_FUN_ARG\u5b8f\uff0c\u7136\u6211\u4eec\u770b\u770b\u8fd9\u4e2a\u5b8f\u5230\u5e95\u90fd\u505a\u4e9b\u4ec0\u4e48\u3002

#define REQ_FUN_ARG(I, VAR) \

if (args.Length() IsFunction()) \

return ThrowException(Exception::TypeError( \

String::New(\u201cArgument \u201d #I \u201d must be a function\u201d))); \

Local VAR = Local::Cast(args[I]);

\u5c31\u50cfJavascript\u4e2d\u7684argument\u53d8\u91cf\uff0cv8\u4f7f\u7528\u6570\u7ec4\u4f20\u9012\u6240\u6709\u7684\u53c2\u6570\u3002\u7531\u4e8e\u6ca1\u6709\u4e25\u683c\u7684\u7c7b\u578b\u9650\u5236\uff0c\u6240\u4ee5\u4f20\u9012\u7ed9\u51fd\u6570\u7684\u53c2\u6570\u6570\u76ee\u53ef\u80fd\u548c\u671f\u5f85\u7684\u4e0d\u540c\u3002\u4e3a\u4e86\u5bf9\u7528\u6237\u53cb\u597d\uff0c\u4f7f\u7528\u5982\u4e0b\u7684\u5b8f\u68c0\u6d4b\u4e00\u4e0b\u53c2\u6570\u6570\u7ec4\u7684\u957f\u5ea6\u5e76\u5224\u65ad\u53c2\u6570\u662f\u5426\u662f\u6b63\u786e\u7684\u7c7b\u578b\u3002\u5982\u679c\u4f20\u9012\u4e86\u9519\u8bef\u7684\u53c2\u6570\u7c7b\u578b\uff0c\u8be5\u5b8f\u5c06\u4f1a\u629b\u51faTypeError\u5f02\u5e38\u3002\u4e3a\u7b80\u5316\u53c2\u6570\u7684\u89e3\u6790\uff0c\u76ee\u524d\u4e3a\u6b62\u5927\u591a\u6570\u7684Node.js\u6269\u5c55\u90fd\u6709\u4e00\u4e9b\u672c\u5730\u4f5c\u7528\u57df\u5185\u7684\u5b8f\uff0c\u7528\u4e8e\u7279\u5b9a\u7c7b\u578b\u53c2\u6570\u7684\u68c0\u6d4b\u3002

\u4e8c\u3001\u63ed\u79d8node.js\u4e8b\u4ef6

\u8981\u4f7f\u7528NodeJS\uff0c\u4f60\u9700\u8981\u77e5\u9053\u4e00\u4e2a\u91cd\u8981\u7684\u4e1c\u897f\uff1a\u4e8b\u4ef6\uff08events\uff09\u3002Node\u4e2d\u6709\u5f88\u591a\u5bf9\u8c61\u90fd\u53ef\u4ee5\u89e6\u53d1\u4e8b\u4ef6\uff0cNode
\u7684\u6587\u6863\u4e2d\u6709\u5f88\u591a\u793a\u4f8b\u3002\u4f46\u6587\u6863\u4e5f\u8bb8\u5e76\u4e0d\u80fd\u6e05\u6670\u7684\u8bb2\u89e3\u5982\u4f55\u7f16\u5199\u81ea\u5b9a\u4e49\u4e8b\u4ef6\u4ee5\u53ca\u76d1\u542c\u51fd\u6570\u3002\u5bf9\u4e8e\u4e00\u4e9b\u7b80\u5355\u7684\u7a0b\u5e8f\u4f60\u53ef\u4ee5\u4e0d\u4f7f\u7528\u81ea\u5b9a\u4e49\u4e8b\u4ef6\uff0c\u4f46\u8fd9\u6837\u5f88\u96be\u5e94\u5bf9\u590d\u6742\u7684\u5e94
\u7528\u3002\u90a3\u4e48\u5982\u4f55\u7f16\u5199\u81ea\u5b9a\u4e49\u4e8b\u4ef6\uff1f\u9996\u5148\u9700\u8981\u4e86\u89e3\u7684\u662f\u5728node.js\u4e2d\u7684\u2019events\u2019\u6a21\u5757\u3002

\u5feb\u901f\u6982\u89c8

\u8981\u8bbf\u95ee\u6b64\u6a21\u5757\uff0c\u53ea\u9700\u4f7f\u7528\u5982\u4e0b\u8bed\u53e5\uff1a

require(\u2018events\u2019)
requires(\u2018events\u2019).EventEmitter

\u7279\u522b\u8bf4\u660e\uff0cnode\u4e2d\u6240\u6709\u80fd\u89e6\u53d1\u4e8b\u4ef6\u7684\u5bf9\u8c61\u57fa\u672c\u4e0a\u90fd\u662f\u540e\u8005\u7684\u5b9e\u4f8b\u3002\u8ba9\u6211\u4eec\u521b\u5efa\u4e00\u4e2a\u7b80\u5355\u7684\u6f14\u793a\u7a0b\u5e8fDummy\uff1a

dummy.js

view plaincopy to clipboardprint?

// basic imports
var events = require(\u2018events\u2019);

// for us to do a require later
module.exports = Dummy;

function Dummy() {
events.EventEmitter.call(this);
}
10.

11. // inherit events.EventEmitter

12. Dummy.super_ = events.EventEmitter;

13. Dummy.prototype = Object.create(events.EventEmitter.prototype, {

14. constructor: {
15. value: Dummy,
16. enumerable: false
17. }

18. });

// basic imports

var events = require(\u2018events\u2019);

// for us to do a require later

module.exports = Dummy;

function Dummy() {

events.EventEmitter.call(this);

}

// inherit events.EventEmitter

Dummy.super_ = events.EventEmitter;

Dummy.prototype = Object.create(events.EventEmitter.prototype, {

constructor: {

value: Dummy,

enumerable: false

}

});

\u4e0a\u8ff0\u4ee3\u7801\u4e2d\u91cd\u70b9\u5c55\u793a\u5982\u4f55\u4f7f\u7528EventEmitter\u6269\u5145\u5bf9\u8c61\uff0c\u5e76\u4ece\u4e2d\u7ee7\u627f\u6240\u6709\u7684\u539f\u578b\u5bf9\u8c61\uff0c\u65b9\u6cd5\u2026\u7b49\u7b49\u3002

\u73b0\u5728\uff0c\u6211\u4eec\u5047\u8bbeDummy\u6709\u4e00\u4e2acooking()\u7684\u65b9\u6cd5\uff0c\u4e00\u65e6\u628a\u98df\u7269\u505a\u719f\u4e4b\u540e\u5b83\u4f1a\u89e6\u53d1\u2019cooked\u2019\u4e8b\u4ef6\uff0c\u5e76\u8c03\u7528\u4e00\u4e2a\u540d\u4e3a\u2019eat\u2019\u7684\u56de\u8c03\u51fd\u6570\u3002

dummy-cooking.js

view plaincopy to clipboardprint?

Dummy.prototype.cooking = function(chicken) {
var self = this;
self.chicken = chicken;
self.cook = cook(); // assume dummy function that\u2019ll do the cooking
self.cook(chicken, function(cooked_chicken) {
self.chicken = cooked_chicken;
self.emit(\u2018cooked\u2019, self.chicken);
});

10. return self;

11. }

Dummy.prototype.cooking = function(chicken) {

var self = this;

self.chicken = chicken;

self.cook = cook(); // assume dummy function that\u2019ll do the cooking

self.cook(chicken, function(cooked_chicken) {

self.chicken = cooked_chicken;

self.emit(\u2018cooked\u2019, self.chicken);

});

return self;

}

一、编写Node.js原生扩展

Node.js是一个强大的平台,理想状态下一切都都可以用javascript写成。然而,你可能还会用到许多遗留的库和系统,这样的话使用c++编写Node.JS扩展会是一个不错的注意。

以下所有例子的源代码可在node扩展示例中找到 。

编写Node.js C + +扩展很大程度上就像是写V8的扩展; Node.js增加了一些接口,但大部分时间你都是在使原始的V8数据类型和方法,为了理解以下的代码,你必须首先阅读V8引擎嵌入指南。

Javascript版本的Hello World

在讲解C++版本的例子之前,先让我们来看看在Node.js中用Javascript编写的等价模块是什么样子。这是一个最简单的Hello World,也不是通过HTTP,但它展示了node模块的结构,而其接口也和大多数C++扩展要提供的接口差不多:

HelloWorldJs = function() {

this.m_count = 0;

};

HelloWorldJs.prototype.hello = function()

{

this.m_count++;

return “Hello World”;

};

exports.HelloWorldJs = HelloWorldJs;

正如你所看到的,它使用prototype为HelloWorldJs类创建了一个新的方法。请注意,上述代码通过将HelloWorldJS添加到exports变量来暴露构造函数。

要在其他地方使用该模块,请使用如下代码:

var helloworld = require(‘helloworld_js’);

var hi = new helloworld.HelloWorldJs();

console.log(hi.hello()); // prints “Hello World” to stdout

C++版本的Hello World

要开始编写C++扩展,首先要能够编译Node.js(请注意,我们使用的是Node.js 2.0版本)。本文所讲内容应该兼容所有未来的0.2.x版本。一旦编译安装完node,编译模块就不在需要额外的东西了。

完整的源代码可以在这里找到 。在使用Node.js或V8之前,我们需要包括相关的头文件:

#include <v8.h>

#include <node.h>

using namespace node;

using namespace v8;

在本例子中我直接使用了V8和node的命名空间,使代码更易于阅读。虽然这种用法和谷歌的自己的C++编程风格指南相悖,但由于你需要不停的使用V8定义的类型,所以目前为止的大多数node的扩展仍然使用了V8的命名空间。

接下来,声明HelloWorld类。它继承自node::ObjectWrap类 ,这个类提供了几个如引用计数、在V8内部传递contex等的实用功能。一般来说,所有对象应该继承ObjectWrap:

class HelloWorld: ObjectWrap

{

private:

int m_count;

public:

声明类之后,我们定义了一个静态成员函数,用来初始化对象并将其导入Node.js提供的target对象中。设个函数基本上是告诉Node.js和V8你的类是如何创建的,和它将包含什么方法:

static Persistent<FunctionTemplate> s_ct;

static void Init(Handle<Object> target)

{

HandleScope scope;

Local<FunctionTemplate> t = FunctionTemplate::New(New);

s_ct = Persistent<FunctionTemplate>::New(t);

s_ct->InstanceTemplate()->SetInternalFieldCount(1);

s_ct->SetClassName(String::NewSymbol(“HelloWorld”));

NODE_SET_PROTOTYPE_METHOD(s_ct, “hello”, Hello);

target->Set(String::NewSymbol(“HelloWorld”),

s_ct->GetFunction());

}

在上面这个函数中target参数将是模块对象,即你的扩展将要载入的地方。(译著:这个函数将你的对象及其方法连接到
这个模块对象,以便外界可以访问)首先我们为New方法创建一个FunctionTemplate,将于稍后解释。我们还为该对象添加一个内部字段,并命
名为HelloWorld。然后使用NODE_SET_PROTOTYPE_METHOD宏将hello方法绑定到该对象。最后,一旦我们建立好这个函数模板后,将他分配给target对象的HelloWorld属性,将类暴露给用户。

接下来的部分是一个标准的C++构造函数:

HelloWorld() :

m_count(0)

{

}

~HelloWorld()

{

}

接下来,在::New 方法中V8引擎将调用这个简单的C++构造函数:

static Handle<Value> New(const Arguments& args)

{

HandleScope scope;

HelloWorld* hw = new HelloWorld();

hw->Wrap(args.This());

return args.This();

}

此段代码相当于上面Javascript代码中使用的构造函数。它调用new HelloWorld
创造了一个普通的C++对象,然后调用从ObjectWrap继承的Wrap方法,
它将一个C++HelloWorld类的引用保存到args.This()的值中。在包装完成后返回args.This(),整个函数的行为和
javascript中的new运算符类似,返回this指向的对象。

现在我们已经建立了对象,下面介绍在Init函数中被绑定到hello的函数:

static Handle<Value> Hello(const Arguments& args)

扩展阅读:c++教程 ... 为什么不建议开内存扩展 ... c++源程序的扩展名是什么 ... 五级流水线cpu设计 ... 五级流水线步骤 ... 扩展c++到62就不动了 ... vs已安装如何增加c++扩展 ... 小米内存扩展的弊端 ... 手机内存扩展的利与弊 ...

本站交流只代表网友个人观点,与本站立场无关
欢迎反馈与建议,请联系电邮
2024© 车视网