Problems calling VC++ dll from C#

AndyGAndyG Posts: 3
edited January 14, 2009 7:41PM in PInvoke.Net

I'm struggling to call a legacy API from C#.

One of the calls I need to make takes a structure that contains, amongst other things, lots of fixed length char arrays.

I thought that I'd managed to create a matching definition in my C# code but when I debug the legacy API, all of the elements of the structure that are fixed length char arrays appear with a null terminator (character 0) as the last character - this has overwritten my actual last character of the string.

I based the C# structures on the document "Default Marshaling for Strings" (

Here is an example of the first two elements of the structure. The legacy api struct definition starts with

struct CLASS_EXPORT SoeMstItem
char ORDNUM [ 6];
char CUSTID [ 7];

(Note that this may have a #pragma pack (4) before the definition).

The C# struct definition starts as

internal struct SoeMstItem
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
internal string ORDNUM; // 6
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 7)]
internal string CUSTID; // 7

When I set up the structure, I do the following

SoeMstItem header = new SoeMstItem();
header.ORDNUM = "123456";
header.CUSTID = "1234567";

When I get into the legacy api in the VC++ debugger, ORDNUM is set to "12345" + character 0 and CUSTID is set to "123456" + character 0. So the buffers are the correct length but the marshalling appears to have done something with null terminated strings.

Does anyone have any suggestions about where I'm going wrong?
Thanks in advance


  • After a few more hours playing around, the only way that I have found to make this work is to declare the elements of the structure as follows

    internal struct SoeMstItem
    [MarshalAs(UnmanagedType.ByValArray, SizeConst=6)]
    internal byte [] ORDNUM;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst=7)]
    internal byte [] CUSTID;

    Then set the values with

    header.ORDNUM = StrToByteArray("123456");
    header.CUSTID = StrToByteArray("1234567");

    public static byte[] StrToByteArray(string str)
    System.Text.ASCIIEncoding encoding=new System.Text.ASCIIEncoding();
    return encoding.GetBytes(str);

    This is not exactly pleasant as I need to remember to pad each string out to it's correct length with spaces otherwise I get marshalling exceptions.

    A simpler solution would be helpful if anyone can assist.
Sign In or Register to comment.