使用c#调用返回struct数组的非托管dll函数

本文关键字:dll 函数 数组 调用 返回 struct 使用 | 更新日期: 2023-09-27 18:16:56

我有一个使用c++编写的非托管dll。我能够轻松地从我的c#应用程序调用一些函数。但是有一个函数让我很难受:)

c++

日志参数有问题。它应该反映为Data_Struct类型的数组:

typedef struct
{
unsigned int    id;
unsigned short  year;
unsigned char   month;
unsigned char   day;
unsigned char   hour;
unsigned char   min;
unsigned char   sec;
unsigned char   status; 
}Data_Struct;
int Read_Stored_Data(HUNIT pUnitHandle, int option, int updateFlag, 
                     int maxEntries, unsigned char *log)

c# (my conversion)

public struct Data_Struct
{
    public uint id;
    public ushort year;
    public byte month;
    public byte day;
    public byte hour;
    public byte min;
    public byte sec;
    public byte status;
}
[DllImport("SData.dll", EntryPoint = "Read_Stored_Data")]
public static extern int Read_Stored_Data(int pUnitHandle, int option, 
    int updateFlag, int maxEntries, ref Data_Struct[] log);

请假设我通过正确的值传递pUnitHandle, option, updateFlag, maxEntries。问题是最后一个参数(log):

Data_Struct[] logs = new Data_Struct[1000];
res = Read_Stored_Data(handle, 1, 0, 1000, ref logs); // This should work but it 
                                                      // causes the application 
                                                      // to terminate!

任何想法?

使用c#调用返回struct数组的非托管dll函数

尝试使用PInvoke属性。

具体来说,是将布局应用于结构体:

[StructLayout(LayoutKind.Sequential)]
public struct Data_Struct
{
    public uint id;
    public ushort year;
    public byte month;
    public byte day;
    public byte hour;
    public byte min;
    public byte sec;
    public byte status;
}

并对参数应用编组属性,同时删除ref:

[DllImport("SData.dll", EntryPoint = "Read_Stored_Data")]
public static extern int Read_Stored_Data(int pUnitHandle, int option,
    int updateFlag, int maxEntries, [MarshalAs(UnmanagedType.LPArray), Out()] Data_Struct[] log);

看看是否有帮助,做相应调整。