扩展V8,增强javascript的功能,典型案例就是nodejs。
//1.函数
v8::Handle LogCallback(const v8::Arguments& args)
{
printf("log: ");
for (int i = 0; i < args.Length(); i++) {
v8::String::Utf8Value str(args[i]);
const char* cstr = *str;
printf("%s ", cstr);
}
printf("\n");
return v8::Undefined();
}
//1.静态变量
static wchar_t sname[512] = {0};
static v8::Handle NameGetter(v8::Local name,
const v8::AccessorInfo& info) {
return v8::String::New((const uint16_t *)sname);
}
static void NameSetter(v8::Local name,
v8::Local value,
const v8::AccessorInfo& info) {
v8::Local str = value->ToString();
str->Write((uint16_t *)sname);
}
//3.类
class Student {
private:
unsigned int age;
wchar_t name[512];
public:
wchar_t address[512];
public:
Student(unsigned int age, wchar_t *name) {
this->age = age;
wcscpy_s(this->name, name);
}
unsigned int getAge() {
return this->age;
}
void setAge(unsigned int nage) {
this->age = nage;
}
wchar_t *getName() {
return this->name;
}
void setName(wchar_t *nname) {
wcscpy_s(this->name, nname);
}
};
v8::Handle StudentConstructor(const v8::Arguments& args){
v8::Handle object = args.This();
int age = args[0]->Uint32Value();
v8::String::Value str(args[1]);
wchar_t* name = (wchar_t*) *str;
Student *student = new Student(age, name);
object->SetInternalField(0, v8::External::New(student));
return object;
}
v8::Handle StudentGetAge(const v8::Arguments& args){
v8::Local self = args.Holder();
v8::Local wrap = v8::Local::Cast(self->GetInternalField(0));
void *ptr = wrap->Value();
return v8::Integer::New(static_cast(ptr)->getAge());
}
v8::Handle StudentSetAge(const v8::Arguments& args)
{
v8::Local self = args.Holder();
v8::Local wrap = v8::Local::Cast(self->GetInternalField(0));
void* ptr = wrap->Value();
static_cast(ptr)->setAge(args[0]->Uint32Value());
return v8::Undefined();
}
v8::Handle StudentGetName(const v8::Arguments& args){
v8::Local self = args.Holder();
v8::Local wrap = v8::Local::Cast(self->GetInternalField(0));
void *ptr = wrap->Value();
return v8::String::New((const uint16_t *)static_cast(ptr)->getName());
}
v8::Handle StudentSetName(const v8::Arguments& args)
{
v8::Local self = args.Holder();
v8::Local wrap = v8::Local::Cast(self->GetInternalField(0));
void* ptr = wrap->Value();
bool b = args[0]->IsString();
v8::String::Value str(args[0]);
static_cast(ptr)->setName((wchar_t *)*str);
return v8::Undefined();
}
static v8::Handle StudentAddressGetter(v8::Local name, const v8::AccessorInfo& info)
{
v8::Handle obj = info.This();
Student& p = *static_cast (v8::Local::Cast(obj->GetInternalField(0))->Value ());
return v8::String::New((const uint16_t *)p.address);
}
static void StudentAddressSetter(v8::Local name, v8::Local value, const v8::AccessorInfo& info) {
v8::Handle obj = info.This();
Student& p = *static_cast (v8::Local::Cast(obj->GetInternalField(0))->Value ());
v8::Local str = value->ToString();
str->Write((uint16_t *)p.address);
}
JNIEXPORT jstring JNICALL Java_javascript_V8_practice(JNIEnv *env, jobject obj, jstring js)
{
if (js == NULL)
return NULL;
v8::HandleScope handle_scope;
v8::Handle global = v8::ObjectTemplate::New();
//1.函数
global->Set("log", v8::FunctionTemplate::New(LogCallback));
//2.静态变量
global->SetAccessor(v8::String::New("name"), NameGetter, NameSetter);
v8::Handle defautNameValue = v8::String::New("samuel");
global->Set("name",defautNameValue);
//3.类
//3.1首先,创建一个新的函数模板,将其与字符串”Student”绑定,并放入 global:
v8::Handle Student_template = v8::FunctionTemplate::New(StudentConstructor);
Student_template->SetClassName(v8::String::New("Student"));
global->Set(v8::String::New("Student"), Student_template);
//3.2成员函数
v8::Handle Student_proto = Student_template->PrototypeTemplate();
Student_proto->Set("getAge", v8::FunctionTemplate::New(StudentGetAge));
Student_proto->Set("setAge", v8::FunctionTemplate::New(StudentSetAge));
Student_proto->Set("getName", v8::FunctionTemplate::New(StudentGetName));
Student_proto->Set("setName", v8::FunctionTemplate::New(StudentSetName));
//3.3成员变量
Student_proto->SetAccessor(v8::String::New("address"), StudentAddressGetter, StudentAddressSetter);
//3.4模板实例化
v8::Handle Student_inst = Student_template->InstanceTemplate();
Student_inst->SetInternalFieldCount(1);
//end
v8::Persistent context = v8::Context::New(NULL, global);
v8::Context::Scope context_scope(context);
const jchar * jcstr = env->GetStringChars(js, 0);
v8::Handle source = v8::String::New(jcstr);
env->ReleaseStringChars(js, jcstr);
v8::Handle script = v8::Script::Compile(source);
v8::Handle result = script->Run();
if (result->IsObject())
{
std::wstring objJson = CV8Helper::ObjToJson(result->ToObject());
result = v8::String::New((jchar *)objJson.c_str());
}
// 备忘:这是另外的方式读取javascript对象。
// if (varName != NULL)
// {
// const jchar * jVarName = env->GetStringChars(varName, 0);
// Local
//
// jchar *pObjName = (jchar *)wcstok((wchar_t *)jVarName, L".");
//
// while (pObjName != NULL)
// {
// Local objValue = jsObj->Get(String::New(pObjName));
// result = objValue;
// jsObj = objValue->ToObject();
// pObjName = (jchar *)wcstok(NULL, L".");
// }
// env->ReleaseStringChars(varName, jVarName);
// }
context.Dispose();
v8::String::Utf8Value retValue(result);
jstring rtstr = env->NewStringUTF(*retValue);