gpt4 book ai didi

c++ - 在 Node.js 和 v8 中调用使用包装对象作为参数的函数

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:51:38 26 4
gpt4 key购买 nike

我想在 node.js 中做类似下面的事情...

var a = new A();var b = new B();

//onTick 应该是一个以 B 的实例作为参数的函数

a.onTick = 函数(bInst){....

a.loop();

意味着 A 有一个属性“onTick”,它是一个在循环内调用的函数。请注意,A 和 B 被定义为 C++ 包装函数,这里是定义

void AClass::Init(Handle<Object> target) {
Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
tpl->SetClassName(String::NewSymbol("A"));
tpl->InstanceTemplate()->SetInternalFieldCount(1);
tpl->PrototypeTemplate()->Set(String::NewSymbol("tick"),
FunctionTemplate::New(Tick)->GetFunction());
tpl->PrototypeTemplate()->Set(String::NewSymbol("loop"),
FunctionTemplate::New(Loop)->GetFunction());

constructor = Persistent<Function>::New(tpl->GetFunction());
constructor->InstanceTemplate()->SetAccessor(String::New("onTick"), GetOnTick, SetOnTick);
target->Set(String::NewSymbol("A"), constructor);
}

Handle<Value> AClass::New(const v8::Arguments &args) {
HandleScope scope;
AClass* acls = new AClass();
WrappedAClass* wrappedA = new WrappedAClass();
acls->wrappedAInst_ = wrappedA;
window->Wrap(args.This());
return args.This();
}
Handle<Value> AClass::Loop(const Arguments &args) {
HandleScope scope;
AClass* acls = ObjectWrap::Unwrap<AClass>(args.This());
acls->wrappedInst_->loop();
return scope.Close(Undefined());
}

我相信这就是您设置属性的 getter 和 setter 的方式

Handle<Function> GetOnTick(Local<String> property, const AccessorInfo& info) {
AClass* acls = ObjectWrap::Unwrap<AClass>(info.Holder());
return acls->onTick_;
}

void SetOnTick(Local<String> property, Local<Function> value, const AccessorInfo& info) {
AClass* acls = ObjectWrap::Unwrap<AClass>(info.Holder());

acls->onTick_ = Persistent<Function>::New(value);
//Here's where I know I'm doing it wrong
void func(WrappedClassB* wcb) {
const unsigned argc = 1;
Local<Value> argv[argc] =
{ Local<Value>::New(BClass::Instantiate(wcb)) };
acls->onTick_->Call(Context::GetCurrent()->Global(), argc, argv);
}
acls->wrappedAInst_->setTickFunc(func);
}

我想做的是从设置 onTick 中获取函数(它接受类 B 的实例)并将其包装在一个函数中以实例化一个新的 BClass。

无论如何这是 BClass 的定义

Persistent<Function> BClass::constructor;
BClass::BClass() {
}
BClass::~BClass() {
}

void BClass::Init(Handle<Object> target) {
Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
tpl->SetClassName(String::NewSymbol("B"));
tpl->InstanceTemplate()->SetInternalFieldCount(1);
constructor = Persistent<Function>::New(tpl->GetFunction());
target->Set(String::NewSymbol("B"), constructor);
}

Handle<Value> BClass::New(const v8::Arguments &args) {
HandleScope scope;
BClass* bcls = new BClass();
bcls->Wrap(args.This());
WrappedBClass* wrappedB = new WrappedBClass();
bcls->wrappedBInst_ = wrappedB;
return args.This();
}
Handle<Value> BClass::Instantiate(const WrappedBClass &wbc) {
HandleScope scope;
//I know the following is wrong but it shows what I am trying to do
BClass* bcls = new BClass();
bcls->wrappedBInst_ = wbc;
return scope.Close(Local<v8::Value>::New(bcls));
}

AClass 和 BClass 都使用另一个 C++ 类并将实例保存为属性(wrappedBInst、wrappedAInst)我相信当我需要将 WrappedBClass 的实例转换为 BClass 时我需要 Instantiate 函数。

WrappedBClass 没有做任何特别的事情,但是 WrappedAClass 继承了一个类,它有一个循环和一个 onTick 函数,而 onTick 函数是我需要调用我的 Javascript 函数的地方,所以在 WrappedAClass 中我覆盖了 onTick 并添加了一个 setTickFunc 函数。

class WrappedAClass : public InheritedClass{
public:
void setTickFunc(void (*func)(WrappedBClass*)){
tickFunc = func;
}
protected:
void tickFunc;
virtual void onTick(WrappedBClass* wbc){
if(tickFunc){
tickFunc(wbc);
}
}
}

所以我认为我可以进入循环并使用 javascript 函数作为 onTick 函数的唯一方法是首先将 javascript 函数包装到 c++ 函数中,然后通过调用 setTickFunc() 设置该函数。我这样做的方式正确吗?

我是一个不错的程序员,但最近才开始使用 C++,所以请原谅我明显的错误,最大的错误很可能是这样的:

void SetOnTick(Local<String> property, Local<Function> value, const AccessorInfo& info) {
AClass* acls = ObjectWrap::Unwrap<AClass>(info.Holder());

acls->onTick_ = Persistent<Function>::New(value);
//Here's where I know I'm doing it wrong
void func(WrappedClassB* wcb) {
const unsigned argc = 1;
Local<Value> argv[argc] =
{ Local<Value>::New(BClass::Instantiate(wcb)) };
acls->onTick_->Call(Context::GetCurrent()->Global(), argc, argv);
}
acls->wrappedAInst_->setTickFunc(func);
}

我仍在尝试弄清楚如何创建一个匿名函数来保存来自外部的变量值 (acls)。我认为闭包在这里无效,关键是这个函数只有一个参数(WrappedClassB* wcb),因为它需要设置为 OnTick 函数。

最佳答案

您不必在 C++ 中创建匿名函数。也许你可以定义你的 WrappedAClass像这样。

class WrappedAClass : public InheritedClass{
public:
void setTickFunc(Local<Function> jsFn){
HandleScope scope;
jsTickFunc = Persistent<Function>::New(jsTickFunc);
}
protected:
Persistent<Function> jsTickFunc;
virtual void onTick(WrappedBClass* wbc){
HandleScope scope;
if(jsTickFunc.IsEmpty())
return;
const unsigned argc = 1;
Local<Value> argv[argc] =
{ Local<Value>::New(BClass::Instantiate(wcb)) };
jsTickFunc->Call(Context::GetCurrent()->Global(), argc, argv);
}
}

关注SetOnTick函数,第二个参数的类型是Local<Value>不是Local<Function> . C++不像js,是静态类型语言。也许你可以定义你的 SetOnTick塞特舔这个:

void SetOnTick(Local<String> property, Local<Value> value, const AccessorInfo& info){
AClass* acls = ObjectWrap::Unwrap<AClass>(info.Holder());
if (value->IsFunction())
acls->wrappedAInst_->setTickFunc(Local<Function>::Cast(value));
}

关于c++ - 在 Node.js 和 v8 中调用使用包装对象作为参数的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15516841/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com