微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C ++ / WinRT运行时组件返回大数组

如何解决C ++ / WinRT运行时组件返回大数组

我正在尝试使用C ++ / WinRT编写Windows运行时组件,该组件将从C#中用于统一程序。我是全新的C ++,但是花了很长时间,我设法通过返回通过Windows API来的Windows.Graphics.Imaging.softwareBitmap对象来使代码正常工作。但是返回SoftwareBitmap的过程很慢,我将代码更改为返回com_array

返回com_array确实可以大大加快速度,但是现在我经常遇到访问冲突读取位置xxxxx 错误。作为在C ++方面经验有限的人,我正在努力做到这一点。下面是我的代码的简化版本。为了简单起见,我删除了大多数代码

1.FrameData

#FrameData.idl

runtimeclass FrameData
    {
        RMFrameData();
        BYTE[] imageArray;
    }

#FrameData.h
struct FrameData : FrameData <RMFrameData>
{
    RMFrameData() = default;
    ~RMFrameData();

    com_array<uint8_t>& imageArray();
    void imageArray(array_view<uint8_t const> value);

private:
    com_array<uint8_t> m_imageArray{};
};

#FrameData.cpp
 RMFrameData::~RMFrameData()
 {
     m_imageArray.clear();
 }
com_array<uint8_t>& RMFrameData::imageArray()
{
    return m_imageArray;
}
void RMFrameData::imageArray(array_view<uint8_t const> value)
{
    m_imageArray = winrt::com_array<BYTE>(std::move_iterator(value.begin()),std::move_iterator(value.end()));
}

使用FrameData发送数据的方法如下。

void PVProcessor::OnFrameArrived(const MediaFrameReader& sender,const MediaFrameArrivedEventArgs& args)
    {

        if (MediaFrameReference frame = sender.TryAcquireLatestFrame())
        {
            auto frame_data = winrt::make_self<winrt::HL2CV_WRT::implementation::RMFrameData>();

            if (frame != nullptr && frame.VideoMediaFrame() != nullptr) {
    
                uint32_t pixelBufferDataLength = 0;
                uint8_t* pixelBufferData;
                SoftwareBitmap bitmap = SoftwareBitmap::Convert(frame.VideoMediaFrame().softwareBitmap(),BitmapPixelFormat::Bgra8);
                if (bitmap != nullptr) {
                    BitmapBuffer bitmapBuffer = bitmap.LockBuffer(BitmapBufferAccessMode::Read);

                    auto spMemoryBufferByteAccess{ bitmapBuffer.CreateReference().as<::Windows::Foundation::IMemoryBufferByteAccess>() };
                    winrt::check_hresult(spMemoryBufferByteAccess->GetBuffer(&pixelBufferData,&pixelBufferDataLength));

                    std::vector<BYTE> pixelVectorData{};
                    pixelVectorData.insert(pixelVectorData.end(),std::make_move_iterator(pixelBufferData),std::make_move_iterator(pixelBufferData + pixelBufferDataLength));
                    frame_data->imageArray(pixelVectorData); //set com_array here.
                    bitmap.Close();
                }

            }
            frame.Close();
            m_frame_data_available(*this,*frame_data);
        }
    }

使用C#中FrameData的方法如下。

void OneFrameAvailable(object sender,RMFrameData e){
  
        var array = e.imageArray;
        
 /*
    use array data here
 */
    }

代码var array = e.imageArray;抛出错误访问冲突读取位置xxxx

我的问题是

  1. 如何在 FrameData.h 中正确初始化m_imageArray
  2. 在C#中使用析构函数后,析构函数是否正确清理了m_imageArray
  3. 使用帧数据后是否需要从C#代码显式调用析构函数
  4. 我写的C ++代码就像Java一样,所以我肯定有很多错误。请让我知道其他需要纠正的事情。
  5. 目标是能够从softwarebitmap访问c#的数据,而无需一路复制。怎么样? 谢谢。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。