Я хочу использовать функцию, которая требует, чтобы я передавал ей в качестве параметра пустой указатель на начало блока памяти. Чтобы эта функция работала правильно, данные должны быть непрерывными в памяти.
Сейчас мои данные хранятся в IVector<IInspectable>
. Глядя на схему памяти этого IVector
в отладчике, я вижу, что между моими данными находится 28 байтов. Который я считаю 7 указателями функций из IUnknown
и IInspectable
. Как я могу получить основное непрерывное распределение памяти моих данных?
UPDATE :
Вот решение, которое я придумал.
Вместо использования 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 ++, что решает мою первоначальную проблему. Это работает, но мне интересно, может ли быть более простой / лучший способ?