编组 C++二维定长char数组作为结构体成员

发布于 2024-08-21 13:12:45 字数 965 浏览 6 评论 0原文

我正在尝试调用一个非托管 C++ 函数,该函数具有一个结构作为输入参数。 该结构在头文件中定义如下:

struct MyStruct
{
int     siOrder;
char     aaszNames[6][25];
int     siId[6];
int     siTones[6];        
};

我尝试将托管结构声明如下:

[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;
}

但没有成功。我猜测封送处理会失败,因为 aaszNames 实际上是一个由 6 个 25 长空终止字符串组成的数组。 我尝试将 aaszNames 声明为

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

在必要时用空值填充数组。但是,再一次,什么也没有。

我有什么遗漏的吗?我东什么错了?编组这个二维字符数组的最佳方法是什么?

任何提示,请。

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:

struct 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

夕色琉璃 2024-08-28 13:12:45

尝试使用多个 C# 结构:

[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;
}

这就是我传递 C 风格字符串数组的方式。

不要忘记创建 aaszNames 的内容!编组器讨厌空引用。

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

祝你好运!

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!

听,心雨的声音 2024-08-28 13:12:45
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst=150)]
 public char[] aaszNames;

这种编组类型看起来不错。可能是函数调用中出现问题,或者内存分配错误/

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

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

中性美 2024-08-28 13:12:45

我会编写一个小型 C 程序来检查 C 结构的字节大小。
然后我会按照其他建议逐个字段提取数据。
从 C 的角度来看,/0 被视为包含在 6 个字节中的普通字符,而 C# 将使用长度 5 并隐藏 /0。

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.

岛歌少女 2024-08-28 13:12:45
char aaszNames[6][25];

C++类型的char是8位~

但是C#类型的char是Unicode,(16位)!

所以 C++ 类型的 char <-> C# 类型的字节

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文