我想使用一个函数,该函数要求我将指向内存块开头的空指针作为参数传递给它。数据必须在内存中是连续的,此功能才能正常工作。
现在,我的数据存储在IVector<IInspectable>
中。在调试器中查看此IVector
的内存布局,我发现我的数据之间有28个字节。我认为是来自IUnknown
和IInspectable
的7个函数指针。如何获得数据的基础连续内存分配?
更新: 这是我想出的解决方案。
我没有使用IVector<IInspectable>
,而是使用winrt::vector_base
创建了一个自定义矢量,如下所示:https://docs.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/collections
然后将其包装在Windows运行时组件中,以便可以使用C#中的此自定义矢量。
它看起来像这样:
MyVector.idl
namespace RuntimeComponent1
{
[default_interface]
runtimeclass MyVector
{
MyVector();
void Append(IInspectable in_val);
}
}
MyVector.h
// MyVector.h
#pragma once
#include "MyVector.g.h"
namespace winrt::RuntimeComponent1::implementation
{
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Foundation::Collections;
struct _MyVector :
implements<_MyVector, IVector<int>, IVectorView<int>, IIterable<int>>,
winrt::vector_base<_MyVector, int>
{
auto& get_container() const noexcept
{
return m_values;
}
auto& get_container() noexcept
{
return m_values;
}
private:
std::vector<int> m_values{};
};
struct MyVector : MyVectorT<MyVector, _MyVector>
{
MyVector() = default;
void Append(Windows::Foundation::IInspectable const& in_val);
};
}
namespace winrt::RuntimeComponent1::factory_implementation
{
struct MyVector : MyVectorT<MyVector, implementation::MyVector>
{
};
}
MyVector.cpp
#include "pch.h"
#include "MyVector.h"
using namespace winrt;
namespace winrt::RuntimeComponent1::implementation
{
void MyVector::Append(Windows::Foundation::IInspectable const& in_val)
{
base_type::Append(winrt::unbox_value<int>(in_val));
}
}
用法示例:
C#
MyRuntimeComponent.MyVector my_vec = new RuntimeComponent1.MyVector();
my_vec.Append(2);
my_vec.Append(4);
MyRuntimeComponent.MyControl my_control = new RuntimeComponent0.MyControl();
my_control.do_stuff_with_contiguous_memory(my_vec);
C ++
void MyControl::do_stuff_with_contiguous_memory(RuntimeComponent1::MyVector const& in_data)
{
// Yay data is contiguous
auto contiguous_data = in_data.as<MyVector>()->get_container().data();
}
最终结果是我可以将数据从C#传递到C ++ / WinRT,并且数据在C ++中将是连续的,从而解决了我的原始问题。它可以工作,但我想知道是否有更简单/更好的方法?