[UWP] [C ++] C ++ Lambda捕获和引用统计了Windows运行时对象 [英] [UWP][C++]C++ Lambda capture and reference counted Windows Runtime objects

查看:82
本文介绍了[UWP] [C ++] C ++ Lambda捕获和引用统计了Windows运行时对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


我正在开发一个UWP应用程序,它使用Javascript作为UI和逻辑代码,在C ++中有一些扩展。一个扩展名是WebP解码器。

I'm working on a UWP app that is using Javascript for the UI and logic code with some extensions in C++. One extension is a WebP decoder.


目标是将IAsyncOperation中的WebP图像从C ++ / Native代码直接解码为ImageData的数据缓冲区。我相信我对一个类型为WriteOnlyArray的对象的lambda捕获有一些问题。

The goal is to decode a WebP image in an IAsyncOperation from C++/Native code directly to an ImageData's data buffer. I believe I'm having some problem with the lambda capture of a handle to an object of type WriteOnlyArray.


C ++部分:

The C++ part:

Windows::Foundation::IAsyncOperation<bool>^
WebPDecoder::DecodeRgbaAsyncInto(const Platform::Array<byte>^ input, Platform::WriteOnlyArray<uint8>^ output, int stride) {
    return create_async([input, output, stride]() -> bool {
        auto data = WebPDecodeRGBAInto(input->Data, input->Length, output->Data, output->Length, stride);
        if (data == nullptr) {
            return false;
        }
        return true;
    });
}





Javascript部分:

// _this.decoder = Universal.WebP.WebPDecoder();
//
function decode(data, height, width, canvas) {
    return new Promise(function (resolve, reject) {
        canvas.height = height;
        canvas.width = width;
        var context = canvas.getContext('2d');
        var imageData = context.createImageData(width, height);
        var stride = imageData.data.length / height;
        _this.decoder.decodeRgbaAsyncInto(data, imageData.data, stride).then(function (success) {
            if (success == false) {
                reject(Error("Failed to decode WebP Image"));
                return;
            }
            context.putImageData(imageData, 0, 0);
            context.drawImage(canvas, 0, 0);

            resolve();
        });
    });
}





使用这段代码,我在lambda函数被调用并被销毁之后就崩溃了。崩溃发生在__abi_winrt_ptr_dtor()中。我不确定原因。


With this code I get a crash after the lambda function has been called and is being destroyed. The crash is in __abi_winrt_ptr_dtor(). I am not sure why.


如果我改为使用WriteOnlyArray的参考捕获,如下所述解码在大部分时间都有效,但偶尔会出现崩溃,因为输出似乎变为无效指针。 code style ="margin:0px; padding:1px 5px; border:0px; font-size:13px; font-family:Consolas,Menlo,Monaco,'Lucida Console','Liberation Mono','DejaVu Sans Mono',' Bitstream Vera Sans Mono','Courier New',monospace,sans-serif; background-color:#eff0f1; white-space:pre-wrap"> return
create_async([input,& output,stride]( ) - > bool {


对于这种情况,我怀疑是因为lambda捕获不会增加WriteOnlArray目标的引用计数t并且它在lambda执行之前/期间释放。

For this case I'm suspecting it is because the lambda capture does not increase the reference count of the WriteOnlArray object and it is released before/during lambda execution.


如何在lambda完成之前强制对象可用?

How can I force the object to be available until the lambda is finished?


推荐答案

不,它没有。  lambda基本上是一个你在线写的方法。如果你定义一个采用相同参数并且你把它放在一起的方法,那么最终效果是一样的在create_async调用中。

No, it doesn't.  The lambda is basically a method that you write in line. The end effect is the same if you define a method that takes the same params and you put that inside the create_async call.

在你的情况下,我建议将数组作为方法的返回值返回,而不是返回true或false。当调用失败时,你可以使用null。这样更容易。

In your case I recommend returning the array as the return value of the method rather than returning true or false. You can have a null when the call fails. It is much easier like this.

是的,你应该确保你传递给lambdas的params会在需要的时候保持活着。这个lambda本身就赢了请注意这一点。


And yes, you are supposed to make sure the params you pass to the lambdas will stay alive for as long as needed. The lambda itself won't take care of that.


这篇关于[UWP] [C ++] C ++ Lambda捕获和引用统计了Windows运行时对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆