【问题标题】:Marshall struct with char带 char 的 Marshall 结构
【发布时间】:2011-08-13 23:15:44
【问题描述】:

当将包含单个字符字段的结构从 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++ lib 是使用 GCC 还是 VS(默认编译器选项)构建的?如果没有,我能否希望 'char' 在 GCC 和 VS 上都签名(默认编译器选项)

【问题讨论】:

  • 该字段实际上是一个字符,还是只是填充到方便的 8 位类型(碰巧称为 char)中的其他东西?
  • C++中用于存储小整数

标签: c# c++ marshalling


【解决方案1】:

在 Visual Studio 和 GCC 中,charsigned by default/J 编译器选项(-funsigned-char 用于 GCC)可用于使其无符号。

所以答案取决于您的 C++ 项目中是否使用了该选项。

【讨论】:

    【解决方案2】:

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

    如果可能,最好的选择是在 C++ 代码中明确表示,即使用signed charunsigned char。然后,您可以根据需要为 C# 编组选择 sbytebyte

    【讨论】:

      【解决方案3】:

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

      • 如果将其作为无符号值存储在 C# 变量中,则将其编组为 UnmanagedType.U1
      • 如果将其作为有符号值存储在 C# 变量中,则将其编组为 UnmanagedType.I1

      关键是,一旦该字节跨越模块边界,重要的是按位表示,而不是 C# 代码中的逻辑表示。到达 C++ 代码后,无符号值 255 等效于有符号值 -1。


      当然,这假设您使用char 作为字符类型。在对问题的评论中,您声明您将其用作整数类型,在这种情况下,您需要决定是否对其进行签名并相应地编组。

      【讨论】:

      • 是的,我明白这一点,看来我的答案现在只是关于 C++ char 规范......
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-01
      • 2014-11-01
      • 1970-01-01
      • 2020-08-14
      • 2012-10-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多