Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/412.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript v8-HeapObject::GetHeap()中崩溃-未初始化值_Javascript_C++_V8 - Fatal编程技术网

Javascript v8-HeapObject::GetHeap()中崩溃-未初始化值

Javascript v8-HeapObject::GetHeap()中崩溃-未初始化值,javascript,c++,v8,Javascript,C++,V8,我从JS调用C++函数,如下所示: var req = new IO.HttpRequest(IO.RequestType.get); req.data({ i: 'jTKvNf9w' }).send('http://pastebin.com/raw.php', function (content) { console.log(content); }); void XmlHttpRequest::open(const Utils::String& str, ::JS::Function

我从JS调用C++函数,如下所示:

var req = new IO.HttpRequest(IO.RequestType.get);
req.data({ i: 'jTKvNf9w' }).send('http://pastebin.com/raw.php', function (content) { console.log(content); });
void XmlHttpRequest::open(const Utils::String& str, ::JS::FunctionObjPtr callback) {
    mCallback = callback;
    mRequest->open(str);
}
class FunctionObj
{
    v8::Handle<v8::Value> mHandle;

public:
    FunctionObj(v8::Handle<v8::Value>& fun) {
        mHandle = fun;
    }

    FunctionObj() { }

    operator bool () {
        return mHandle.IsEmpty() == false;
    }

    template<typename... Args>
    void callVoid(const Args&... args) {
        std::vector<v8::Handle<v8::Value>> arguments;
        addArgument(arguments, args...);

        v8::TryCatch tc;
        v8::Handle<v8::Function>::Cast(mHandle)->Call(mHandle, arguments.size(), arguments.data());
        if (tc.HasCaught()) {
            throw JS::Exception(tc.Exception(), tc.StackTrace());
        }
    }
};
请求以异步方式处理,完成后调用回调。在C++中,发送函数看起来如下:

var req = new IO.HttpRequest(IO.RequestType.get);
req.data({ i: 'jTKvNf9w' }).send('http://pastebin.com/raw.php', function (content) { console.log(content); });
void XmlHttpRequest::open(const Utils::String& str, ::JS::FunctionObjPtr callback) {
    mCallback = callback;
    mRequest->open(str);
}
class FunctionObj
{
    v8::Handle<v8::Value> mHandle;

public:
    FunctionObj(v8::Handle<v8::Value>& fun) {
        mHandle = fun;
    }

    FunctionObj() { }

    operator bool () {
        return mHandle.IsEmpty() == false;
    }

    template<typename... Args>
    void callVoid(const Args&... args) {
        std::vector<v8::Handle<v8::Value>> arguments;
        addArgument(arguments, args...);

        v8::TryCatch tc;
        v8::Handle<v8::Function>::Cast(mHandle)->Call(mHandle, arguments.size(), arguments.data());
        if (tc.HasCaught()) {
            throw JS::Exception(tc.Exception(), tc.StackTrace());
        }
    }
};
之后,如果请求完成:

void XmlHttpRequest::onComplete(Utils::String content) {
    sUIMgr->getDispatcher()->pushFrame(Gl::Dispatcher::Priority::Low, [this, content]() {
        ::JS::FunctionObjPtr f = mCallback;
        f->callVoid(content);
    });
}
推送框架将函数放入一个队列中,以便在设置所有脚本的主线程中执行

现在问题出在
callVoid
HeapObject::GetHeap()调用
MemoryChunk::FromAddress(reinterpret_cast(this))->heap()时,我遇到了访问冲突。这些是v8功能。问题是,HeapObject中的
这个
指针是0xCCCC,这意味着它是一个未初始化的值。
这个
-指针来自存储在JS::FunctionObjPtr(std::shared\u ptr的typedef)中的句柄

起初我认为我的
函数obj
有问题。我通过以下方式获得:

template<typename T>
static TYPE_RET(FunctionObjPtr) ObjectWrap::unwrap(v8::Handle<v8::Value>& value) {
    if (value->IsFunction() == false) {
        TYPE_ERR("Value is not a function");
    }

    return std::make_shared<FunctionObj>(value);
}
当我在其“注册”的
XmlHttpRequest::open
中调用函数时,它会工作。因此,一开始我认为对象会被gc'ed,但为了确保它永远不会在FunctionObj::FunctionObj中被收集,我从句柄创建了一个v8::Persistent。但它还是崩溃了。我甚至让v8::Persistent弱来看看它是否真的被收集,但是弱回调永远不会被调用

电话前我检查过的其他事项:

  • v8::Isolate::GetCurrent()->返回输入的正确隔离
  • v8::Context::GetCurrent()->相同
  • 全局手柄镜未被保留
  • open和具有该调用的lambda在同一线程中被调用
  • 进一步资料:
    这不仅限于v8::Handle。如果我尝试存储一个对象并稍后访问它的一个属性,也会发生这种情况。我就是无法在使用手柄的lambda内部找到任何东西。

    正如我在尝试的内容中所说的,我查看了
    v8::Persistent
    。结果我用错了

    我所做的:

    class FunctionObj
    {
        v8::Handle<v8::Value> mHandle;
        v8::Persistent<v8::Value> mPersistent;
    public:
        FunctionObj(v8::Handle<v8::Value>& fun) {
            mPersistent.Reset(v8::Isolate::GetCurrent(), fun);
            mHandle = fun;
        }
    
        FunctionObj() { }
    
        operator bool () {
            return mHandle.IsEmpty() == false;
        }
    
        template<typename... Args>
        void callVoid(const Args&... args) {
            std::vector<v8::Handle<v8::Value>> arguments;
            addArgument(arguments, args...);
    
            v8::TryCatch tc;
            v8::Handle<v8::Function>::Cast(mHandle)->Call(mHandle, arguments.size(), arguments.data());
            if (tc.HasCaught()) {
                throw JS::Exception(tc.Exception(), tc.StackTrace());
            }
        }
    };
    
    类函数对象
    {
    v8::手柄手柄;
    持久性mPersistent;
    公众:
    FunctionObj(v8::Handle&fun){
    mPersistent.Reset(v8::Isolate::GetCurrent(),fun);
    mHandle=乐趣;
    }
    FunctionObj(){}
    运算符bool(){
    返回mHandle.IsEmpty()==false;
    }
    模板
    void callVoid(常量参数和…参数){
    向量参数;
    添加参数(参数、参数…);
    v8::TryCatch tc;
    v8::Handle::Cast(mHandle)->调用(mHandle,arguments.size(),arguments.data());
    if(tc.hascapt()){
    抛出JS::Exception(tc.Exception(),tc.StackTrace());
    }
    }
    };
    
    我应该做的事

    class FunctionObj
    {
        v8::Persistent<v8::Value> mPersistent;
    public:
        FunctionObj(v8::Handle<v8::Value>& fun) {
            mPersistent.Reset(v8::Isolate::GetCurrent(), fun);
        }
    
        FunctionObj() { if(mPersistent) { mPersistent.Dispose(); } }
    
        operator bool () {
            return mHandle.IsEmpty() == false;
        }
    
        template<typename... Args>
        void callVoid(const Args&... args) {
            std::vector<v8::Handle<v8::Value>> arguments;
            addArgument(arguments, args...);
    
            v8::Local<v8::Function> fun = v8::Local<v8::Function>::New(v8::Isolate::GetCurrent(), mPersistent.As<v8::Function>());
    
            v8::TryCatch tc;
            fun->Call(fun, arguments.size(), arguments.data());
            if (tc.HasCaught()) {
                throw JS::Exception(tc.Exception(), tc.StackTrace());
            }
        }
    };
    
    类函数对象
    {
    持久性mPersistent;
    公众:
    FunctionObj(v8::Handle&fun){
    mPersistent.Reset(v8::Isolate::GetCurrent(),fun);
    }
    FunctionObj(){if(mPersistent){mPersistent.Dispose();}
    运算符bool(){
    返回mHandle.IsEmpty()==false;
    }
    模板
    void callVoid(常量参数和…参数){
    向量参数;
    添加参数(参数、参数…);
    v8::Local fun=v8::Local::New(v8::Isolate::GetCurrent(),mPersistent.As());
    v8::TryCatch tc;
    fun->Call(fun,arguments.size(),arguments.data());
    if(tc.hascapt()){
    抛出JS::Exception(tc.Exception(),tc.StackTrace());
    }
    }
    };
    
    我创建的持久性并不意味着我存储的句柄不会被销毁,而是意味着以后可以查询对象的新句柄,并且对象不会被删除


    现在一切都像一个符咒

    不知道这是否有帮助,但如果您存储对象并希望稍后访问其属性,请尝试使用持久指针类型。e、 g.持久化模块_handle=Persistent::New(目标);这有帮助。这并不是问题的直接原因(因为我已经尝试了持久性解决方案),但它让我继续坚持下去,这是正确的方向,请看我的答案。