用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源码

Google V8扩展利器发布:v8-native-binding-generator的更多相关文章

  1. 解决高版本 Google Chrome 扩展程序强制停用问题 -摘自网络

    1]前往这里下载你喜欢的语言的组策略模板 后缀为.adm (其他的文件自己看 https://docs.google.com/viewer?a=v&pid=sites&srcid=Y2 ...

  2. Chrome浏览器扩展开发系列之一:初识Google Chrome扩展

    1.       Google Chrome扩展简介 Google Chrome扩展是一种软件,以增强Chrome浏览器的功能. Google Chrome扩展使用HTML.JavaScript.CS ...

  3. V8世界探险 (1) - v8 API概览

    版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/lusing/article/detai ...

  4. 15个网页设计必备的Google Chrome 扩展

    2011年第一篇,翻译自freelancefolder的一篇文章.以下为译文内容: 最近,我将Google Chrome作为了我的主力浏览器,同时,将其作为我设计和开发网页的工具,尽管我还时常会去Fi ...

  5. 使用CoreRT将.NET Core发布为Native应用程序

    在上一篇文章<使用.NET Core快速开发一个较正规的命令行应用程序>中我们看到了使用自包含方式发布的.NET Core应用中包含了216个文件.我就写一个cat命令用得着这么动真格.. ...

  6. Chrome V8系列--浅析Chrome V8引擎中的垃圾回收机制和内存泄露优化策略

    V8 实现了准确式 GC,GC 算法采用了分代式垃圾回收机制.因此,V8 将内存(堆)分为新生代和老生代两部分. 一.前言 V8的垃圾回收机制:JavaScript使用垃圾回收机制来自动管理内存.垃圾 ...

  7. SPI:Java的高可扩展利器

    摘要:JAVA SPI,基于接口的编程+策略模式+配置文件的动态加载机制. 本文分享自华为云社区<一文讲透Java核心技术之高可扩展利器SPI>,作者: 冰 河. SPI的概念 JAVA ...

  8. Aspose.Pdf v8.4.1 发布

    .NET v8.4.1: 修复的错误及漏洞: PDF到JPEG时,内容从最终JPEG文件中丢失. 书签缩放识别错误.  Java v4.2: 新特性: 搜索分离超过两行的文本. 修复的异常: PDF到 ...

  9. 添加了有道生词本的 chrome google翻译扩展和有道翻译扩展

    在chrome发布项目,需要先花美金认证,还得要美国ID,无奈. 直接上源码,需手动导入. 原始项目源码并未开源,个人是从chrome本地文件里拿出来的,拓展来的,侵删(本来想着自已写一个,业余时间, ...

随机推荐

  1. EasyUI-标签(Tabs)用法

    用法示例 创建tabs 1. 经由标记创建Tabs 从标记创建Tabs更容易,我们不需要写任何JavaScript代码.记住把 'easyui-tabs' 类添加到<div/>标记,每个t ...

  2. AutoIt实现selenium上传文件

    1,安装autoIt 2,工程中建文件夹,例如:script,将autoit 复制到该文件夹,并且编辑视频所在的文件夹的路径,编辑"au3"格式的文件 3,编辑完成后生成EXE文件 ...

  3. ThreadLocal实现线程范围内共享

    线程范围内共享,即是对相同一段代码,在不同的模块调用时使用一份数据,而在另外一个线程中又使用另外一份数据. ThreadLocal使用set方法为一个新的线程增加一条记录,key是各自的线程,valu ...

  4. pip安装使用详解

    pip类似RedHat里面的yum,安装Python包非常方便.本节详细介绍pip的安装.以及使用方法. 1.pip下载安装 1.1 pip下载   1 # wget "https://py ...

  5. MUI 个推

    个推 四种消息模板(透传消息模板.点击通知打开网页模板.点击通知打开应用模板.点击通知栏弹框下载模版) 三种推送方式(对单个用户推送接口 | 对指定用户列表推送接口 | 对指定应用群推接口) 四种消息 ...

  6. Storm系列之二——Guaranteeing Message Processing

    Storm保证每跳离开spout的消息都会被完全处理.本文介绍Storm是怎么保证每条消息都被完全处理并且作为用户该怎么做才能从Storm的可靠性保证受益. 1.什么叫消息被完全处理? 一个tuple ...

  7. fragment (1)简单示例:定义,界面配置,fragment之间的跳转

    fragment作用 同一程序中切换界面 比activity轻快,灵活. fragment代码示例 ide  : android studio 1.2 sdk : 22 package com.exa ...

  8. C# 正则表达式 转自-每日一bo

    最近写爬虫时需要用到正则表达式,有段时间没有使用正则表达式现在渐渐感觉有些淡忘,现在使用还需要去查询一些资料.为了避免以后这样的情况,在此记录下正则表达式的一些基本使用方法附带小的实例.让以后在使用时 ...

  9. SqlSever基础 dateadd month 增加五个月

    镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...

  10. CG基础教程-陈惟老师十二讲笔记

    转自 麽洋TinyOcean:http://www.douban.com/people/Tinyocean/notes?start=50&type=note 因为看了陈惟十二讲视频没有课件,边 ...