将C方法绑定到现有JS函数原型的最简单方法是什么?
发布时间:2020-12-16 07:31:33 所属栏目:百科 来源:网络整理
导读:我有几个简单的C类,例如: class Audio {public: Audio(const char *filename,bool async = true); ~Audio(); Audio *play(int fade = 0); Audio *pause(); Audio *loop(int loops = -1); Audio *volume(float volume); 我在JavaScript中复制了如下结构: va
我有几个简单的C类,例如:
class Audio { public: Audio(const char *filename,bool async = true); ~Audio(); Audio *play(int fade = 0); Audio *pause(); Audio *loop(int loops = -1); Audio *volume(float volume); 我在JavaScript中复制了如下结构: var Audio = function(filename,async) {}; Audio.prototype.Play = function(fade) {}; Audio.prototype.Pause = function() {}; Audio.prototype.Loop = function(loops) {}; Audio.prototype.Volume = function(volume) {}; 在阅读了v8,v8-juice和大量博客的文档和来源之后……我找不到关于如何用C方法“覆盖”JS函数的单一参考. 理想情况下,我希望JS能够控制类创建/销毁(这可能吗?),并且这些对象总是指向我的原生函数(PrototypeTemplate?). 今天我认真地花了一整天阅读与此相关的文章/博客/代码,找不到,我希望的是一个简单的答案. 为了你的缘故,对我来说一个“简单”的回答将是这些方面的东西(包装对我来说很好;如果我必须为创建/破坏写包装,那就没关系): v8::Local<v8::Function> jsAudioFunction = v8::Local<v8::Function>::Cast(v8::Context::GetCurrent()->Global()->Get(v8::String::New("Audio"))); jsAudioFunction->Setup(/* setup constructor/destructor */); jsAudioFunction->SetPrototype(/* map native methods to js functions */); 解决方法
虽然这不能解决将本机代码绑定到JS对象的问题,但以下是我的工作成果:
static void jsAudioGC(v8::Persistent<v8::Value> object,void *data) { v8::Persistent<v8::Object> obj = v8::Persistent<v8::Object>::Cast(object); Audio *audio = static_cast<Audio*>(obj->GetPointerFromInternalField(0)); if (audio != NULL) { obj->SetPointerInInternalField(0,NULL); v8::V8::AdjustAmountOfExternalAllocatedMemory(-sizeof(audio)); delete audio; } object.Dispose(); } v8::Handle<v8::Value> jsAudio(const v8::Arguments &args) { v8::Persistent<v8::Object>::New(args.This()).MakeWeak(NULL,jsAudioGC); Audio *audio = new Audio(get(args[0],""),get(args[1],true)); v8::V8::AdjustAmountOfExternalAllocatedMemory(sizeof(audio)); args.This()->SetPointerInInternalField(0,audio); return args.This(); } v8::Handle<v8::Value> jsAudioPlay(const v8::Arguments &args) { Audio *audio = static_cast<Audio*>(args.This()->GetPointerFromInternalField(0)); if (audio != NULL) audio->play(get(args[0],0)); return args.This(); } 我的init()函数内部: v8::Handle<v8::FunctionTemplate> audio = v8::FunctionTemplate::New(&jsAudio); audio->PrototypeTemplate()->Set("Play",v8::FunctionTemplate::New(&jsAudioPlay)); audio->InstanceTemplate()->SetInternalFieldCount(1); globals->Set("Audio",audio); 这完全符合我的要求;包括适当的实例化和垃圾收集. 我对这种方法的唯一遗憾是我希望能够“只使用定义的东西”.这样,这些函数仅在包含JS“类”时才可用(使得可以在JS IDE中定义和记录所有函数). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |