您的位置:首页 > 编程语言 > Go语言

Google V8扩展利器发布:v8-native-binding-generator

2015-08-18 06:01 435 查看
用C++扩展Google V8很简单,但是类比较多时还是很烦的。前段时间开发cantk-runtime-v8时,我写了一个代码产生器v8-native-binding-generator,让扩展Google V8变得非常方便,甚至无需要了解V8本身。具体用法如下:

先写一个JSON的类描述文件,下面这段JSON是我用来模拟XMLHttpRequest的:

{
"className":"HttpClient",
"functions":[
{
"name":"send",
"returnType" : "bool",
"args"   : [
{"name":"onProgress", "type":"function"},
{"name":"onDone", "type":"function"}
]
}
],
"attributes" : [
{"name":"url", "type":"string"},
{"name":"returnType", "type":"string"},
{"name":"method", "type":"string"},
{"name":"requestHeaders", "type":"string"},
{"name":"requestData", "type":"string"},
{"name":"status", "type":"int32_t"},
{"name":"statusText", "type":"string"},
{"name":"responseHeaders", "type":"string"},
{"name":"responseText", "type":"string"}
]
}


运行代码产生器:

node gen-v8-binding.js idl/http_client.json


生成4个文件,依次是HttpClient类的头文件和CPP文件,HttpClientBinding类的头文件和CPP文件:

HttpClient.h

#ifndef _HTTPCLIENT_H
#define _HTTPCLIENT_H

#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <v8.h>
#include <nan/nan.h>

using namespace std;
using namespace v8;

class HttpClient: public ObjectWrap {
public:
HttpClient();
~HttpClient();

bool send(NanCallback*  onProgress, NanCallback*  onDone);

string getUrl() const;
void setUrl(string url);

string getReturnType() const;
void setReturnType(string returnType);

string getMethod() const;
void setMethod(string method);

string getRequestHeaders() const;
void setRequestHeaders(string requestHeaders);

string getRequestData() const;
void setRequestData(string requestData);

int32_t getStatus() const;
void setStatus(int32_t status);

string getStatusText() const;
void setStatusText(string statusText);

string getResponseHeaders() const;
void setResponseHeaders(string responseHeaders);

string getResponseText() const;
void setResponseText(string responseText);

private:
string _url;
string _returnType;
string _method;
string _requestHeaders;
string _requestData;
int32_t _status;
string _statusText;
string _responseHeaders;
string _responseText;
};

#endif


HttpClient.cpp

#include "HttpClient.h"
HttpClient::HttpClient(){
}

HttpClient::~HttpClient(){
}

bool HttpClient::send(NanCallback*  onProgress, NanCallback*  onDone) {
}

string HttpClient::getUrl() const {
return this->_url;
}

void HttpClient::setUrl(string url) {
this->_url = url;
}

string HttpClient::getReturnType() const {
return this->_returnType;
}

void HttpClient::setReturnType(string returnType) {
this->_returnType = returnType;
}

string HttpClient::getMethod() const {
return this->_method;
}

void HttpClient::setMethod(string method) {
this->_method = method;
}

string HttpClient::getRequestHeaders() const {
return this->_requestHeaders;
}

void HttpClient::setRequestHeaders(string requestHeaders) {
this->_requestHeaders = requestHeaders;
}

string HttpClient::getRequestData() const {
return this->_requestData;
}

void HttpClient::setRequestData(string requestData) {
this->_requestData = requestData;
}

int32_t HttpClient::getStatus() const {
return this->_status;
}

void HttpClient::setStatus(int32_t status) {
this->_status = status;
}

string HttpClient::getStatusText() const {
return this->_statusText;
}

void HttpClient::setStatusText(string statusText) {
this->_statusText = statusText;
}

string HttpClient::getResponseHeaders() const {
return this->_responseHeaders;
}

void HttpClient::setResponseHeaders(string responseHeaders) {
this->_responseHeaders = responseHeaders;
}

string HttpClient::getResponseText() const {
return this->_responseText;
}

void HttpClient::setResponseText(string responseText) {
this->_responseText = responseText;
}


HttpClientBinding.h

#ifndef _HTTPCLIENTBINDING_H
#define _HTTPCLIENTBINDING_H

#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>

#include <string.h>

#include <v8.h>
#include <nan/nan.h>

using namespace v8;
void HttpClientInitBinding(Handle<Object> target);

#endif


HttpClientBinding.cpp

#include "HttpClient.h"

#include "HttpClientBinding.h"

NAN_METHOD(newHttpClient) {
NanScope();

HttpClient* obj = new HttpClient();
obj->Wrap(args.This());

NanReturnValue(args.This());
}

NAN_METHOD(HttpClientSend) {
NanScope();
HttpClient* obj = ObjectWrap::Unwrap<HttpClient>(args.This());

if(args.Length() == 2) {
NanCallback* onProgress = new NanCallback(args[0].As<Function>());
NanCallback* onDone = new NanCallback(args[1].As<Function>());

bool retVal = obj->send(onProgress, onDone);
NanReturnValue(NanNew<Boolean>(retVal));
return;
}

}

NAN_GETTER(HttpClientGetUrl) {
NanScope();
HttpClient* obj = ObjectWrap::Unwrap<HttpClient>(args.This());
NanReturnValue(NanNew<String>(obj->getUrl()));
}

NAN_SETTER(HttpClientSetUrl) {
NanScope();
HttpClient* obj = ObjectWrap::Unwrap<HttpClient>(args.This());
if (value->IsString()) {
v8::String::Utf8Value nativeValue(value);
obj->setUrl(*nativeValue);
}else{
printf("invalid data type for HttpClient.url\n");
}
}

NAN_GETTER(HttpClientGetReturnType) {
NanScope();
HttpClient* obj = ObjectWrap::Unwrap<HttpClient>(args.This());
NanReturnValue(NanNew<String>(obj->getReturnType()));
}

NAN_SETTER(HttpClientSetReturnType) {
NanScope();
HttpClient* obj = ObjectWrap::Unwrap<HttpClient>(args.This());
if (value->IsString()) {
v8::String::Utf8Value nativeValue(value);
obj->setReturnType(*nativeValue);
}else{
printf("invalid data type for HttpClient.returnType\n");
}
}

NAN_GETTER(HttpClientGetMethod) {
NanScope();
HttpClient* obj = ObjectWrap::Unwrap<HttpClient>(args.This());
NanReturnValue(NanNew<String>(obj->getMethod()));
}

NAN_SETTER(HttpClientSetMethod) {
NanScope();
HttpClient* obj = ObjectWrap::Unwrap<HttpClient>(args.This());
if (value->IsString()) {
v8::String::Utf8Value nativeValue(value);
obj->setMethod(*nativeValue);
}else{
printf("invalid data type for HttpClient.method\n");
}
}

NAN_GETTER(HttpClientGetRequestHeaders) {
NanScope();
HttpClient* obj = ObjectWrap::Unwrap<HttpClient>(args.This());
NanReturnValue(NanNew<String>(obj->getRequestHeaders()));
}

NAN_SETTER(HttpClientSetRequestHeaders) {
NanScope();
HttpClient* obj = ObjectWrap::Unwrap<HttpClient>(args.This());
if (value->IsString()) {
v8::String::Utf8Value nativeValue(value);
obj->setRequestHeaders(*nativeValue);
}else{
printf("invalid data type for HttpClient.requestHeaders\n");
}
}

NAN_GETTER(HttpClientGetRequestData) {
NanScope();
HttpClient* obj = ObjectWrap::Unwrap<HttpClient>(args.This());
NanReturnValue(NanNew<String>(obj->getRequestData()));
}

NAN_SETTER(HttpClientSetRequestData) {
NanScope();
HttpClient* obj = ObjectWrap::Unwrap<HttpClient>(args.This());
if (value->IsString()) {
v8::String::Utf8Value nativeValue(value);
obj->setRequestData(*nativeValue);
}else{
printf("invalid data type for HttpClient.requestData\n");
}
}

NAN_GETTER(HttpClientGetStatus) {
NanScope();
HttpClient* obj = ObjectWrap::Unwrap<HttpClient>(args.This());
NanReturnValue(NanNew<Int32>(obj->getStatus()));
}

NAN_SETTER(HttpClientSetStatus) {
NanScope();
HttpClient* obj = ObjectWrap::Unwrap<HttpClient>(args.This());
if (value->IsInt32()) {
int32_t nativeValue = value->Int32Value();
obj->setStatus(nativeValue);
}else{
printf("invalid data type for HttpClient.status\n");
}
}

NAN_GETTER(HttpClientGetStatusText) {
NanScope();
HttpClient* obj = ObjectWrap::Unwrap<HttpClient>(args.This());
NanReturnValue(NanNew<String>(obj->getStatusText()));
}

NAN_SETTER(HttpClientSetStatusText) {
NanScope();
HttpClient* obj = ObjectWrap::Unwrap<HttpClient>(args.This());
if (value->IsString()) {
v8::String::Utf8Value nativeValue(value);
obj->setStatusText(*nativeValue);
}else{
printf("invalid data type for HttpClient.statusText\n");
}
}

NAN_GETTER(HttpClientGetResponseHeaders) {
NanScope();
HttpClient* obj = ObjectWrap::Unwrap<HttpClient>(args.This());
NanReturnValue(NanNew<String>(obj->getResponseHeaders()));
}

NAN_SETTER(HttpClientSetResponseHeaders) {
NanScope();
HttpClient* obj = ObjectWrap::Unwrap<HttpClient>(args.This());
if (value->IsString()) {
v8::String::Utf8Value nativeValue(value);
obj->setResponseHeaders(*nativeValue);
}else{
printf("invalid data type for HttpClient.responseHeaders\n");
}
}

NAN_GETTER(HttpClientGetResponseText) {
NanScope();
HttpClient* obj = ObjectWrap::Unwrap<HttpClient>(args.This());
NanReturnValue(NanNew<String>(obj->getResponseText()));
}

NAN_SETTER(HttpClientSetResponseText) {
NanScope();
HttpClient* obj = ObjectWrap::Unwrap<HttpClient>(args.This());
if (value->IsString()) {
v8::String::Utf8Value nativeValue(value);
obj->setResponseText(*nativeValue);
}else{
printf("invalid data type for HttpClient.responseText\n");
}
}

static Persistent<FunctionTemplate> constructor;
void HttpClientInitBinding(Handle<Object> target) {
NanScope();
Local<FunctionTemplate> ctor = NanNew<FunctionTemplate>(newHttpClient);
NanAssignPersistent(constructor, ctor);
ctor->InstanceTemplate()->SetInternalFieldCount(1);
ctor->SetClassName(NanNew("HttpClient"));
Local<ObjectTemplate> proto = ctor->PrototypeTemplate();

proto->SetAccessor(NanNew("url"), HttpClientGetUrl, HttpClientSetUrl);
proto->SetAccessor(NanNew("returnType"), HttpClientGetReturnType, HttpClientSetReturnType);
proto->SetAccessor(NanNew("method"), HttpClientGetMethod, HttpClientSetMethod);
proto->SetAccessor(NanNew("requestHeaders"), HttpClientGetRequestHeaders, HttpClientSetRequestHeaders);
proto->SetAccessor(NanNew("requestData"), HttpClientGetRequestData, HttpClientSetRequestData);
proto->SetAccessor(NanNew("status"), HttpClientGetStatus, HttpClientSetStatus);
proto->SetAccessor(NanNew("statusText"), HttpClientGetStatusText, HttpClientSetStatusText);
proto->SetAccessor(NanNew("responseHeaders"), HttpClientGetResponseHeaders, HttpClientSetResponseHeaders);
proto->SetAccessor(NanNew("responseText"), HttpClientGetResponseText, HttpClientSetResponseText);

NAN_SET_PROTOTYPE_METHOD(ctor, "send", HttpClientSend);

target->Set(NanNew("HttpClient"), ctor->GetFunction());

}


目前支持的数据类型有:

* 1.string 字符串

* 2.int32_t 整数

* 3.int64_t 整数

* 4.double 浮点数

* 5.bool 布尔变量

* 6.function 回调函数(目前只能用于参数)

* 7.其它对象指针(如Image*),要求对象的类也是用本工具产生出来的。

更多例子请参考:https://github.com/drawapp8/cantk-runtime-v8

1.v8-native-binding-generator源码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: