如何获取IVector <iinspectable>

时间:2019-01-06 00:07:36

标签: windows-runtime c++-winrt

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

现在,我的数据存储在IVector<IInspectable>中。在调试器中查看此IVector的内存布局,我发现我的数据之间有28个字节。我认为是来自IUnknownIInspectable的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 ++中将是连续的,从而解决了我的原始问题。它可以工作,但我想知道是否有更简单/更好的方法?

0 个答案:

没有答案