开发者

Marshaling a C++ two-dimensional fixed length char array as a structure member

开发者 https://www.devze.com 2022-12-20 09:42 出处:网络
I am trying to call an unmanaged C++ function, that has a structure as an input parameter. The structure is defined in the header file like this:

I am trying to call an unmanaged C++ function, that has a structure as an input parameter. The structure is defined in the header file like this:

开发者_如何学Pythonstruct MyStruct
{
int     siOrder;
char     aaszNames[6][25];
int     siId[6];
int     siTones[6];        
};

I tried to declare the managed struct as following:

[StructLayoutAttribute(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct MyStruct {

public int siOrder;

[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst=150)]
public string aaszNames;

[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst=6, ArraySubType=UnmanagedType.I4)]
public int[] siId;

[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst=6, ArraySubType=UnmanagedType.I4)]
public int[] siTones;
}

But without any success. I am guessing that the marshaling fails, since the aaszNames is actually an array of six 25 long null-terminating strings. I tried declaring aaszNames as

 [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst=150)]
 public char[] aaszNames;

filling the array with nulls where necessary. But, again, nothing.

Is there something I am missing? What am I dong wrong? What is the best way to marshal this 2-D char array?

Any hints, please.


Try using multiple C# structs:

[StructLayoutAttribute(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct MyStruct_Name
{
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 25)]
    public string name;
}

[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct MyStruct
{
    public int siOrder;

    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 6)]
    public MyStruct_Name aaszNames;

    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 6, ArraySubType = UnmanagedType.I4)]
    public int[] siId;

    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 6, ArraySubType = UnmanagedType.I4)]
    public int[] siTones;
}

This is how I've been passing arrays of C-style strings around.

Don't forget to create the contents of aaszNames! The marshaller hates null references.

MyStruct foo = new MyStruct();
for (int i = 0; i < 6; i++)
{
    foo.aaszNames[i] = new MyStruct_Name();
    foo.aaszNames[i].name = "";
}

Good luck!


[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst=150)]
 public char[] aaszNames;

That marshalling type looks well. Probably issue in function call, or bad memory allocation/


I would write a small c-program to check the byte size of the C-structure.
Then I would go with the other suggestion to extract the data field by field.
From a C standpoint the /0 is treated as normal character included in the 6 bytes whereas C# would use a length of 5 and have the /0 hidden.


char aaszNames[6][25];

char of C++ Type is 8 bits~

but char of C# Type is Unicode ,(16 bits) !

so char of C++ Type <-> byte of C# type

0

精彩评论

暂无评论...
验证码 换一张
取 消