简体   繁体   中英

calling unmanaged dll function that returns an array of struct using C#

I am having an unmanaged dll written using C++. I am able to call some functions easily from my C# application. But one function make me suffer :)

C++

The problem is in the log parameter. It should be reflected as an array of the Data_Struct type:

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);

Please assume that I am passing pUnitHandle , option , updateFlag , maxEntries with correct values. The problem is the last parameter ( 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!

Any idea?

Try playing with the PInvoke attributes.

Specifically, apply layout to the struct:

[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;
}

and apply a marshalling attribute to the parameter, while removing 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);

See if that helps, adjust accordingly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM