Reputation: 343
I have one third-party exported function and three structures of the same size, same numer of members but different member types:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1, Size = 34)]
public struct StructA
{
public Int32 id;
public Int16 year;
public Char month;
public Char day;
// and 12 more Char members
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1, Size = 34)]
public struct StructB
{
public Int32 id;
public Int16 year;
public Byte month;
public Byte day;
// and 12 more Byte members
public Int64 padding1;
public Int32 padding2;
public Int16 padding3;
// padding fields supply the 14 bytes left of the total size (34)
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1, Size = 34)]
public struct StructC
{
public Int32 id;
public Int16 year;
public Int16 month;
public Int16 day;
// and 12 more Int16 members
}
private static extern Int32 foo_nction(ref struct structure);
I would expect that StructA and StructC have the same result because they have the same number of parameters in the same order and each parameter correspond not in types but in sizes, but the most similar results are between StructA and StructB despite their types are not equivalent in sizes.
THE FACTS ARE THAT:
When I pass StructA as parameter to the 3rd-party function everything works perfect.
When I pass StructB as parameter its members get the expected values but truncated because Char's physical bytes are two and Byte's is one (as our friendly forum pals remarked).
When I pass StructC as parameter the values from the 3rd-party function melt as if one Int16-type value could storage two Char-type values. For example, when I pass StructA as parameter I receive date data that forms "2013-5-27" and when I pass StructB I receive date data that forms "2013-6917-2"
Could anyone please explain the reason of this behavior?
Upvotes: 0
Views: 146
Reputation: 4693
Update:
Sorry for that I did't build an example for the test. I'd suggest that to have a look at this answer:
Calling C++ function from C#, with lots of complicated input and output parameters
and other answers of that question are also good with more explanation.
I think the whole point is you are confused with [marshaling]. Your data, either structure or array was not passed directly to C++ side, but marshal as what it is, that is, it's copied into a pinned memory, and then passed to the C++ code. The CharSet
is not used to deside the physical length of data but how to interpret the characters.
The physical bytes of Char
is two; but byte
is one. Your data might be truncated.
Upvotes: 3