c++ - C++/WinRT 运行时组件返回大数组
问题描述
我正在尝试使用 C++/WinRT 编写一个 Windows 运行时组件,该组件将从 C# 用于统一程序。我是全新的 C++,但花了很长时间,我设法通过返回 Windows.Graphics.Imaging.SoftwareBitmap
通过 windows API 来的对象来使代码工作。但是返回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。
我的问题是
- 如何
m_imageArray
在FrameData.h中正确初始化。 m_imageArray
在 C# 中使用析构函数后是否正确清理?- 使用帧数据后是否需要从 C# 代码中显式调用析构函数?
- 我像java一样编写C++代码,所以我相信有很多错误。请让我知道其他需要更正的事情。
- 目标是能够访问
softwarebitmap
的数据,c#
而无需一路复制。如何?谢谢。
解决方案
推荐阅读
- java - 如何在 Spring Boot 中通过检查嵌套对象来获取对象?
- c# - 在 .NET MVC 应用程序中处理来自动态子表单的数据输入的最佳方法
- laravel - 如何在 laravel 中测试 back() 方法
- javascript - 在 Google Apps 脚本中从服务器端 (.gs) 传递到客户端 (html) 时,已知类型的变量变为“未定义”
- python - 如何提高 Pytesseract 提取数字的准确性
- excel - VBA中的名称和全名有什么区别?
- git - 如何压缩给定提交后所做的更改?(混帐存档)
- aspnetboilerplate - 是否有任何代码生成器(内置或第三方)可用于为 ASP..NET 样板生成数据库优先代码?
- python - 在数据边界处寻找峰值
- reactjs - undefined 不是 React Native 中的函数