2

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?

2
  • 1
    What happens when you call it? Unbalanced stack? AccessViolationException? Fails silently? Commented Dec 4, 2011 at 11:46
  • fails silently .. doesn't help Commented Dec 4, 2011 at 11:53

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

This worked perfectly. Even though [StructLayout(LayoutKind.Sequential)] is not required.
again got trapped after changing the struct as follows:

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.