c++ - 将结构数组从 C++ DLL 返回到 C# 应用程序

标签 c++ dll interop marshalling

我正在尝试将结构数组从 C++ DLL 返回到 C# 应用程序。我可以从 DLL 返回结构也可以将结构列表从 C# 应用程序发送到 C++ DLL 并打印其数据。 但无法从 DLL 向 C# 应用程序填充和返回结构数组。任何人都可以帮忙吗?以下是我目前正在处理的代码:

C#代码:

[StructLayout(LayoutKind.Sequential)]
public struct DATA
{
    [MarshalAs(UnmanagedType.I4)]
    public int id;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string Name;
};

[DllImport("PassStruct.dll")]
private static extern void PrintListOfStructData(IntPtr[] pD, int nSize);

[DllImport("PassStruct.dll")]
private static extern IntPtr ReturnStruct();

public static DATA ReturnStructure()
{
    DATA oRData = new DATA();
    IntPtr pD = new IntPtr();

    pD = ReturnStruct();
    oRData = (DATA)Marshal.PtrToStructure(pD, typeof(DATA));

    FreeStruct(pD);
    return oRData;
}

public static void PrintListOfStructData(List<NativeDLLHelper.DATA> data)
{
    int NumberOfElements = data.Count;
    DATA oData = new DATA();
    IntPtr[] MemPtr = new IntPtr[NumberOfElements];
    for (int i = 0; i < NumberOfElements; i++)
    {
        MemPtr[i] = Marshal.AllocHGlobal(Marshal.SizeOf(oData));
        Marshal.StructureToPtr(data[i], MemPtr[i], false);
    }

    PrintListOfStructData(MemPtr, NumberOfElements);

    for (int i = 0; i < NumberOfElements; i++)
    {
        Marshal.FreeHGlobal(MemPtr[i]);
    }
}

C++ DLL 代码:

typedef struct _DATA
{
    int          nID;
    wchar_t      *sName;
}DATA;

extern "C" DLLEXPORT DATA* ReturnStruct()
{
    DATA *obj = new DATA();

    obj->nID = 100;
    wstring sName = L"String from DLL";
    obj->sName = ::SysAllocString(sName.c_str());

    return obj;
}

extern "C" DLLEXPORT void PrintListOfStructData(DATA **pD, int nSize)
{
    for(int i=0; i<nSize; i++)
    {
        wcout<<"ID: "<<pD[i]->nID<<endl;
        wcout<<"Name: "<<pD[i]->sName<<endl;
    }
}

extern "C" DLLEXPORT void FreeStruct(DATA *obj)
{
    delete obj;
}

最佳答案

不要将 PrintListOfStructData 声明为采用 IntPtr 数组:

[DllImport("PassStruct.dll")]
private static extern void PrintListOfStructData(IntPtr pD, int nSize);

然后,将所有结构声明到同一个内存块中:

int size = Marshal.SizeOf(typeof(DATA));
IntPtr MemPtr = Marshal.AllocHGlobal(NumberOfElements * size);
try
{
    for (int i = 0; i < NumberOfElements; i++)
    {
        Marshal.StructureToPtr(data[i], IntPtr.Add(MemPtr, i * size), false);
    }

    PrintListOfStructData(MemPtr, NumberOfElements);
}
finally
{
    if (MemPtr != IntPtr.Zero) Marshal.FreeHGlobal(MemPtr);
}

关于c++ - 将结构数组从 C++ DLL 返回到 C# 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22910584/

相关文章:

在其他构造函数的调用中调用构造函数时出现 C++ 编译错误

c# - Unity找不到其他DLL的DLL依赖关系(均在Assets文件夹中)

c++ - 将 native 编译的 C++ DLL 添加到 CLR C++ 项目?

c - 关于将 windbg 用于从 Labview 调用的 dll 的问题

c# - 如何将 native C++ 内存转换为 C# 结构?

javascript - 用于嵌套函数的 Clojurescript Extern

c++ - 模板类的专用构造函数

c++ - 为什么 CMake 使用 Opencv 未正确设置包含目录(MSVC 2010 项目)

c++ - MarmaladeSDK : How to create a project in XCode?

java - 以互操作方式序列化消息的最佳方式是什么?