简体   繁体   中英

C# - behavior of similar structures into a third-party function

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?

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.

Have a look of char and byte .

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