C++写node笔记(七)

2013-01-25 22:49

C++写node笔记(七)

by snoopyxdy

at 2013-01-25 14:49:07

original http://snoopyxdy.blog.163.com/blog/static/60117440201302431946486

最近用c++先后写了3个node_moudle,有2个放到了npm上,一个项目感觉性能不佳,流产了,总结一下吧:
两个上线项目分别是
A、hvalidator
node简单验证模块,主要验证一些数据格式,以及email地址,ip,url等正则判断,这个模块算是第一个node addon的产出,处女作。
npm install hvalidator
B、ccap
利用CImg图形库和libjpeg库让node不用依赖第三方库生成简单验证码。可以设置验证码的大小,内容,质量等。
npm install ccap
github:https://github.com/DoubleSpout/ccap

v8手册handle<value>类:http://bespin.cz/~ondras/html/classv8_1_1Value.html

1、一个node的addon基本入口格式应该如下:

#define BUILDING_NODE_EXTENSION
#include <node.h>
#include "xxx.h"

using namespace v8;
void Init(Handle<Object> target) {
  target->Set(String::NewSymbol("输出属性名"),
           FunctionTemplate::New(C++函数名)->GetFunction());
}
NODE_MODULE(输出模块名, Init)


2、node官方的实例一般都是定义一个class,把要输出给node的方法设置为static静态方法,如下:
#include <node.h>
#include <string>

class SimpleF {
 public:
  static v8::Handle<v8::Value> trim(const v8::Arguments& args);
  static v8::Handle<v8::Value> ltrim(const v8::Arguments& args);
  static v8::Handle<v8::Value> rtrim(const v8::Arguments& args); 
  static v8::Handle<v8::Value> toXss(const v8::Arguments& args);
  static v8::Handle<v8::Value> replace(const v8::Arguments& args);
   
 protected:
  static void toCString(std::string& str, v8::Handle<v8::Value> strp);
  static void lTrimString(std::string& str,const std::string& filters = "\r\t\n ");

 private:
  SimpleF();
  ~SimpleF();
};

比如上面这段代码就定义了一个SimpleF的类,然后定义了很多静态方法供输出给node


3、一个简单的输出给node的静态类方法示例

Handle<Value> SimpleV::isArray(const Arguments& args) {//是否是数组
  HandleScope scope;
  return scope.Close(Boolean::New(args[0]->IsArray()));
}

比如上面这段就是输出给node,并且返回一个bool值,告诉node端第一个参数是否为数组


4、静态方法可以返回给node各种不同的格式,比如整形,字符串,数组,对象等

布尔值:return scope.Close(Boolean::New(1)); //返回true

数字:return scope.Close(Number::New(1)); //返回数字1

字符串:
char *a = '1';
return scope.Close(Number::New(a)); //返回字符串a

数组:
Handle<Array> ary = Array::New(2);
ary->Set(0,Integer::New(1));
ary->Set(1,String::New("m"));
return scope.Close(ary);
//返回数组[1,"m"];

对象:
Handle<Object> obj = Object::New();
obj->Set(String::New("a") ,Integer::New(1));
obj->Set(String::New("b"), String::New("m"));
return scope.Close(obj);
//返回数组{a:1,b:"m"};

函数:
Handle<Value> MyFunction(const Arguments& args) {//这表定义了一个静态方法
  HandleScope scope;
  return scope.Close(String::New("hello world"));
}

Local<FunctionTemplate> tpl = FunctionTemplate::New(MyFunction);//将上面的静态方法作为返回值返回node
Local<Function> fn = tpl->GetFunction();
fn->SetName(String::NewSymbol("theFunction")); // 忽略名字则表示匿名
return scope.Close(fn);


5、获取node传递参数的值
获得数字的值:
double:arg[0]->NumberValue ()
int64_t:arg[0]->IntegerValue ()
uint32_t:arg[0]->Uint32Value ()
int32_t:arg[0]->Int32Value ()

获得布尔值:
bool:arg[0]->BooleanValue ()

获得字符串:
String::Utf8Value utf8_value(arg[0]->ToString());
string& str(*utf8_value);

获得数组,对象
Local<Object> lo(arg[0]->ToObject ());

获得数组或是对象中的某一个值:
Local<Value> ary0 = lo->Get(0); //获取数组中第一个元素的值,返回Local<Value>
获得对象中的某一个值
Local<Value> ary0 = lo->Get(String::New("m")); //获取对象中key字段为m的值,返回Local<Value>

6、一些常用的代码片段:

6.1将node端的字符串传化为std::string类型:

void router::toCString(std::string& str, Handle<Value> strp){
String::Utf8Value utf8_value(strp->ToString());//转化成v8::Utf8Value
str = *utf8_value;//转化为string
}


6.2将c++的std::string转化为char * 返回给node

std::string s;
const char *sp = s.c_str();
return scope.Close(String::New(sp));


6.3 c++的replace函数:

void SimpleF::CSreplace(std::string& s1,std::string& s2,std::string& s3)
{
std::string::size_type pos=0;
std::string::size_type a=s2.size();
std::string::size_type b=s3.size();


while((pos=s1.find(s2,pos))!=std::string::npos)
{
s1.replace(pos,a,s3);
pos+=b;
}

}


6.4 c++linux下和windows下的正则表达式

linux生成正则表达式(这里没有释放,因为要重复使用该正则):

#include <regex.h>

regex_t genRegex(std::string regstr){
regex_t preg;
const char *regex = regstr.c_str();

regcomp(&preg, regex, REG_EXTENDED|REG_NOSUB);
return preg;
}

linux正则匹配:

bool match(regex_t preg,std::string& str){
int z;
const char *buf = str.c_str();
const size_t nmatch = 1;
regmatch_t pm[nmatch];
z = regexec(&preg, buf, nmatch, pm, 0);
return z != REG_NOMATCH;
}


windows下的正则生成,同样没有释放内容,重复使用:

#include <regex>

std::regex genRegex(std::string regstr){
std::regex pattern(regstr,std::regex_constants::extended);
return pattern;
}

windows下正则匹配:

bool match(std::regex pattern,std::string& str){
std::match_results<std::string::const_iterator> result;
bool valid = std::regex_match(str,result,pattern);
return valid;
}


6.5 c++调用node端的函数:

Local<Function> cb = Local<Function>::Cast(args[0]);
const unsigned argc = 1;
Local<Value> argv[argc] = { Local<Value>::New(String::New("hello world")) };
cb->Call(Context::GetCurrent()->Global(), argc, argv);


持续更新。。