1, 匯出全域函數到指令碼環境
// v8test.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <v8.h>#pragma comment(lib, "v8_base.lib")#pragma comment(lib, "v8_snapshot.lib")#pragma comment(lib, "ws2_32.lib")#pragma comment(lib, "winmm.lib")using namespace v8;// 在宿主環境中實現一個常規的println()函數v8::Handle<v8::Value> HostPrint(const v8::Arguments& args) {for (int i = 0; i < args.Length(); i++){v8::HandleScope handle_scope;// 轉換成字串用於列印v8::String::AsciiValue str(args[i]);printf("%s", *str);}printf("\n");// 返回Undefined, 類似於返回voidreturn v8::Undefined();}int main(int argc, char* argv[]) {// Create a stack-allocated handle scope.HandleScope handle_scope;// 建立一個通用範本用於修改指令碼對象 v8::Handle<v8::ObjectTemplate> globalTemplate = v8::ObjectTemplate::New();// 把宿主的HostPrint函數註冊到指令碼環境globalTemplate->Set(v8::String::New("println"), v8::FunctionTemplate::New(HostPrint));// Create a new context.v8::ExtensionConfiguration * extConfig = NULL;// 並且把自訂的通用範本globalTemplate作為參數傳入Handle<Context> context = Context::New(extConfig, globalTemplate);// Enter the created context for compiling and// running the hello world script. Context::Scope context_scope(context);// Create a string containing the JavaScript source code.Handle<String> source = String::New("""println('Hello ', 'world ', 1, ' ', 2, ' ', Math.PI);" // 在指令碼環境中調用宿主函數"");String * str = *source;// Compile the source code.Handle<Script> script = Script::Compile(source);// Run the script to get the result.Handle<Value> result = script->Run();// Dispose the persistent context.(Persistent<Context>(context)).Dispose();return 0;}
2, 運行結果:
Hello world 1 2 3.141592653589793請按任意鍵繼續. . .
3, 匯出靜態變數到指令碼環境
// v8test.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <v8.h>#pragma comment(lib, "v8_base.lib")#pragma comment(lib, "v8_snapshot.lib")#pragma comment(lib, "ws2_32.lib")#pragma comment(lib, "winmm.lib")using namespace v8;// 在宿主環境中定義一個全域變數static int globalVarInV8Host = 0;static Handle<Value> XGetter(Local<String> key,const AccessorInfo& info) {return Integer::New(globalVarInV8Host);}static void XSetter(Local<String> key, Local<Value> value,const AccessorInfo& info) {globalVarInV8Host = value->Int32Value();}// 在宿主環境中實現一個常規的println()函數v8::Handle<v8::Value> HostPrint(const v8::Arguments& args) {for (int i = 0; i < args.Length(); i++){v8::HandleScope handle_scope;// 轉換成字串用於列印v8::String::AsciiValue str(args[i]);printf("%s", *str);}printf("\n");// 返回Undefined, 類似於返回voidreturn v8::Undefined();}int main(int argc, char* argv[]) {// Create a stack-allocated handle scope.HandleScope handle_scope;// 建立通用範本globalTemplatev8::Handle<v8::ObjectTemplate> globalTemplate = v8::ObjectTemplate::New();// 註冊globalVarInV8Host變數的訪問器globalTemplate->SetAccessor(v8::String::New("globalVarInV8Host"), XGetter, XSetter);// 為了查看變數,把HostPrint也註冊進去globalTemplate->Set(v8::String::New("println"), v8::FunctionTemplate::New(HostPrint));// Create a new context.Handle<Context> context = Context::New(NULL, globalTemplate);// Enter the created context for compiling and// running the hello world script. Context::Scope context_scope(context);// Create a string containing the JavaScript source code.Handle<String> source = String::New("""var v1 = globalVarInV8Host;""v1 = 100;""println('v1=', v1, ';', 'globalVarInV8Host=', globalVarInV8Host);""var v2 = globalVarInV8Host;""v2 = 200;""println('v2=', v2, ';', 'globalVarInV8Host=', globalVarInV8Host);""globalVarInV8Host = 300;""println('v1=', v1, ';', 'v2=', v2, ';', 'globalVarInV8Host=', globalVarInV8Host);");String * str = *source;// Compile the source code.Handle<Script> script = Script::Compile(source);// Run the script to get the result.Handle<Value> result = script->Run();// Dispose the persistent context.(Persistent<Context>(context)).Dispose();return 0;}
4, 運行結果:
v1=100;globalVarInV8Host=0v2=200;globalVarInV8Host=0v1=100;v2=200;globalVarInV8Host=300請按任意鍵繼續. . .
5, 匯出動態對象到指令碼環境
// v8test.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <v8.h>#pragma comment(lib, "v8_base.lib")#pragma comment(lib, "v8_snapshot.lib")#pragma comment(lib, "ws2_32.lib")#pragma comment(lib, "winmm.lib")using namespace v8;// 在宿主環境中實現一個常規的println()函數v8::Handle<v8::Value> HostPrint(const v8::Arguments& args) {for (int i = 0; i < args.Length(); i++){v8::HandleScope handle_scope;// 轉換成字串用於列印v8::String::AsciiValue str(args[i]);printf("%s", *str);}printf("\n");// 返回Undefined, 類似於返回voidreturn v8::Undefined();}// 定義一個簡單的c++類class CUser {public:int uid_;public:CUser(int uid): uid_(uid){}virtual ~CUser() { }static Handle<Value> GetUID(Local<String> property,const AccessorInfo &info) {Local<Object> self = info.Holder();Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));void* ptr = wrap->Value();int value = static_cast<CUser*>(ptr)->uid_;return Integer::New(value);}static void SetUID(Local<String> property, Local<Value> value,const AccessorInfo& info) {Local<Object> self = info.Holder();Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));void* ptr = wrap->Value();static_cast<CUser*>(ptr)->uid_ = value->Int32Value();}};/*** Utility function that wraps a C++ object in a* JavaScript object.* 封裝c++對象成為一個js對象*/Handle<Object> WrapUserObject(CUser * pUser) {// Handle scope for temporary handles.HandleScope handle_scope;Handle<ObjectTemplate> templ = ObjectTemplate::New();// 設定內部插槽個數為1,分配一個內部儲存地區templ->SetInternalFieldCount(1);// 設定訪問器templ->SetAccessor(String::New("uid"), CUser::GetUID, CUser::SetUID);// Create an empty http request wrapper.Handle<Object> result = templ->NewInstance();// Store the request pointer in the JavaScript wrapper.result->SetInternalField(0, External::New(pUser));// Return the result through the current handle scope. Since each// of these handles will go away when the handle scope is deleted// we need to call Close to let one, the result, escape into the// outer handle scope.return handle_scope.Close(result);}int main(int argc, char* argv[]) {// Create a stack-allocated handle scope.HandleScope handle_scope;// 建立通用範本globalTemplatev8::Handle<v8::ObjectTemplate> globalTemplate = v8::ObjectTemplate::New();// 為了查看變數,把HostPrint也註冊進去globalTemplate->Set(v8::String::New("println"), v8::FunctionTemplate::New(HostPrint));// Create a new context.Handle<Context> context = Context::New(NULL, globalTemplate);// Enter the created context for compiling and// running the hello world script. Context::Scope context_scope(context);// 建立一個本機物件CUser * pUser = new CUser(12345);// 封裝成一個JS指令碼對象Handle<Object> userObject = WrapUserObject(pUser);// 使用以下方式註冊user對象到全域範圍context->Global()->Set(String::New("user"), userObject);// 以下方式是錯誤的, TODO: 全域對象和代理(proxy)全域對象的區別// http://bespin.cz/~ondras/html/classv8_1_1Context.html// https://wiki.mozilla.org/Gecko:SplitWindow// globalTemplate->Set(String::New("user"), userObject);// Create a string containing the JavaScript source code.Handle<String> source = String::New("""println(user.uid);");String * str = *source;// Compile the source code.Handle<Script> script = Script::Compile(source);// Run the script to get the result.Handle<Value> result = script->Run();// Dispose the persistent context.(Persistent<Context>(context)).Dispose();return 0;}
6, 運行結果
12345請按任意鍵繼續. . .
7, 參考:
https://code.google.com/p/cproxyv8/wiki/Usage
http://iammr.7.blog.163.com/blog/static/49102699201201565822189/
https://developers.google.com/v8/embed
https://wiki.mozilla.org/Gecko:SplitWindow
http://bespin.cz/~ondras/html/classv8_1_1Context.html