首页 > 解决方案 > 如何将结构数组从本机 dll 编组到托管应用程序?

问题描述

我正在尝试将结构数组从本机 dll 传递到 C# 应用程序。我有一个类似于以下的结构:

C++

#define EXPORT __declspec (dllexport)

struct Window
{
    Window(HWND hwnd, std::wstring const& title, std::wstring& className)
    {
        m_hwnd = hwnd;
        m_title = title;
        m_className = className;
    }

    HWND m_hwnd;
    std::wstring m_title;
    std::wstring m_className;
};

extern "C" {
    EXPORT const Window* EnumerateWindows(int* windowCount);
}

这是我们要导出到托管应用程序的函数:

EXPORT const Window* EnumerateWindows(int* windowCount)
{
    std::vector<Window> windows;

    EnumWindows(EnumWindowsProc, reinterpret_cast<LPARAM>(&windows));

    Window* newArray = (Window*)CoTaskMemAlloc(sizeof(Window) * windows.size());

    for (int i = 0; i < windows.size(); i++) {
        newArray[i] = windows[i];
    }

    *windowCount = windows.size();

    return windows.size() ? newArray : nullptr;
}

这是托管代码: C#

        [StructLayout(LayoutKind.Sequential)]
        public struct Window
        {
            public Window(IntPtr hwnd, string title, string className)
            {
                Hwnd = hwnd;
                Title = title;
                ClassName = className;
            }
            public IntPtr Hwnd { get; }
            public string Title { get; }
            public string ClassName { get; }
        }

[DllImport("WindowEnum", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr EnumerateWindows(ref int size);

我想按如下方式使用它:

int size = 0;
var unmanagedArrayOfStructs = EnumerateWindows(ref size);
var managedArrayofStructs = new Window[size];

// Some magical code to marshal unmanagedArrayOfStructs into managedArrayOfStructs

Marshal.FreeCoTaskMem(unmanagedArrayOfStructs);

我的问题是,如何编组结构数组?我知道我可以使用Marshal.Copy()整数值数组,但是在这种情况下显然行不通。

标签: c#c++interoppinvoke

解决方案


推荐阅读