带char的Marshall结构体

Marshall struct with char

本文关键字:结构体 Marshall char      更新时间:2023-10-16

当从c++到c#编组包含单个字符字段的结构时,c#结构的定义应该是什么样的?

[StructLayout(LayoutKind.Sequential, Size = 1), Serializable]
public struct SomeStruct
{
    [MarshalAs(UnmanagedType.I1)]
    public sbyte Field;
}

[StructLayout(LayoutKind.Sequential, Size = 1), Serializable]
public struct SomeStruct
{
    [MarshalAs(UnmanagedType.U1)]
    public byte Field;
}

我找不到一个明确的信息,它应该是一个有符号的字节或不是。(在c++结构定义中声明为'char')

UPD:是否取决于c++库是用GCC还是VS(默认编译器选项)构建的?如果没有,我可以希望'char'在GCC和VS(默认编译器选项)上签名

在c++中,通常无法判断char是有符号的还是无符号的。这取决于实现,通常可以通过选项配置单个编译器(实现),使其成为任意一种方式。

如果可能的话,最好的选择是在c++代码中显式地使用

,即使用signed charunsigned char。然后,您可以根据需要选择sbytebyte进行c#编组。

在Visual Studio和GCC中,char是默认签名的。/J编译器选项(GCC为-funsigned-char)可用于使其无符号。

因此,答案取决于该选项是否在您的c++项目中使用。

答案取决于您喜欢如何在c#中存储值。你应该选择最方便的。

  • 如果你把它作为无符号值存储在c#变量中,那么把它封送为UnmanagedType.U1
  • 如果你把它作为一个有符号的值存储在c#变量中,那么把它封送为UnmanagedType.I1

关键在于,一旦字节越过模块边界,重要的是位表示,而不是c#代码中的逻辑表示。在c++代码中,无符号值255相当于有符号值-1。


当然,这假设您使用char作为字符类型。在问题的注释中,您声明将其用作整数类型,在这种情况下,您需要决定是否对其进行signed和封送。