Passing an array of structs into an unmannaged dll

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Dear All

I have this struct

[StructLayout(LayoutKind.Sequential)]
public struct biodata
{
public ushort weight;
public ushort lenght;
public ushort height;
public uint time;
}

Which I’m trying to pass as an array into this unmanaged function:

[DllImport("unmanaged.dll")]
public static extern void BFillArray (biodata [] aBio, ushort aMaxCount, out
ushort aCount);

By using this call:

biodata [] mRec = new biodata [1500];
ushort mCount = 0;
BFillArray (mRec,1500,out mCount);

Now in the unmanaged dll function BFillArray this happens:

typedef struct _ biodata {
unsigned short weight;
unsigned short lenght;
unsigned short height;
unsigned int time;
} biodata ;

UNMANAGED_API void BFillArray (biodata * aBio, const unsigned short
aMaxCount, unsigned short &aCount)
{
for (aCount = 0; aCount < aMaxCount; aCount ++)
{
aBio [aNo].time = aNo;
aBio [aNo].height = aNo;
aBio [aNo].lenght = aNo;
aBio [aNo].weight = aNo;
}
}

Note also that the “Struct Member Alignment†in the unmanaged project is set
to 1 byte, providing no padding between the values.

So far so good, but when looking into the array returned from the BFillArray
call in the managed code, the entire dataset is corrupted and seems more
like being misaligned. Now the obvious question I’m trying to solve is WHY?

Any suggestions?

Best regards

Eskild
 
Ok, so when I talk about rubbish coming back into the array I mean like this:

mRec[0].time = 0x10000
mRec[0].height = 0x0
mRec[0].lenght = 0x0
mRec[0].weight = 0x0

mRec[0].time = 0x20002
mRec[0].height = 0x1
mRec[0].lenght = 0x1
mRec[0].weight = 0x1

mRec[0].time = 0x30003
mRec[0].height = 0x0
mRec[0].lenght = 0x2
mRec[0].weight = 0x2

mRec[0].time = 0x40004
mRec[0].height = 0x4
mRec[0].lenght = 0x0
mRec[0].weight = 0x3

…

(as seen when tracing into the managed code, after returning from
BFillArray.) So this leads me to think that there is something gone wrong
when marshalling the array of biodata structures Problem is that I’m not yet
sure how to solve this correctly.

e.
 
Ok my mistake. Just to avoid confusion when looking at these data. The Index
value of the array should be increasing like this:

mRec[0].time = 0x10000
mRec[0].height = 0x0
mRec[0].lenght = 0x0
mRec[0].weight = 0x0

mRec[1].time = 0x20002
mRec[1].height = 0x1
mRec[1].lenght = 0x1
mRec[1].weight = 0x1

mRec[2].time = 0x30003
mRec[2].height = 0x0
mRec[2].lenght = 0x2
mRec[2].weight = 0x2

mRec[3].time = 0x40004
mRec[3].height = 0x4
mRec[3].lenght = 0x0
mRec[3].weight = 0x3
Sorry.. I’ll try not to create more problems than necessary. :)
 
In Compact Framework 1.0 StructLayout(LayoutKind.Sequential) does nothing.
You still get automatic layout with 4 byte alignment.
Instead of passing biodata[] to the function, pass a ushort[ biodata.Length
* 5 ]. Upon return walk the array and copy its data into biodata structures
 
4 bytes padding eh? - And I suppose there is no way of controlling that in
the .NET compact 1.0 framework? How about the later versions?

Anyways, to omit the problem I just added two byte padding in my unmanaged
structure, so it looks like this now:

typedef struct _ biodataCharp {
unsigned short weight;
unsigned short lenght;
unsigned short height;
unsigned short padding;
unsigned int time;
} biodataCharp;

Which seems to work fine as I can set the ‘Struct Member Alignment’ to 1 in
the unmanaged eVC project.

Thank you for pointing this out!

:)

e.
 
Eskild said:
4 bytes padding eh? - And I suppose there is no way of controlling that in
the .NET compact 1.0 framework? How about the later versions?

It's implemented in 2.0.
Anyways, to omit the problem I just added two byte padding in my unmanaged
structure, so it looks like this now:

typedef struct _ biodataCharp {
unsigned short weight;
unsigned short lenght;
unsigned short height;
unsigned short padding;
unsigned int time;
} biodataCharp;

Which seems to work fine as I can set the ‘Struct Member Alignment’ to 1
in
the unmanaged eVC project.

Or you could use pragma pack(4) in your C++ project
 
Back
Top