首页 > 解决方案 > 如何获取 IVector 的基础向量

问题描述

我想使用一个函数,该函数需要我将一个指向内存块开头的 void 指针作为参数传递给它。数据必须在内存中连续,此功能才能正常工作。

现在我的数据存储在一个IVector<IInspectable>. 在调试器中查看它的内存布局,IVector我发现我的数据之间有 28 个字节。我认为IUnknown这是来自and的 7 个函数指针IInspectable。如何获得数据的底层连续内存分配?

更新:这是我想出的解决方案。

我没有使用这里推荐的IVector<IInspectable>创建自定义向量: https ://docs.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/collections 并将其包装在 Windows 运行时组件,以便我可以使用 C# 中的这个自定义向量。winrt::vector_base

它看起来像这样:

我的矢量.idl

namespace RuntimeComponent1
{
    [default_interface]
    runtimeclass MyVector 
    {
        MyVector();
        void Append(IInspectable in_val);
    }
}

我的向量.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>
    {
    };
}

我的矢量.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++ 中是连续的,这解决了我原来的问题。它有效,但我想知道是否有更简单/更好的方法?

标签: windows-runtimec++-winrt

解决方案


推荐阅读