带 char 的 Marshall 结构

发布于 2024-11-03 23:12:42 字数 563 浏览 4 评论 0原文

将包含单个 char 字段的结构从 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 上都签名吗(默认编译器选项)

When marshalling struct which contains a single char field from C++ to C# how the C# struct definition should look like?

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

or

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

I can't find a clear info about should it be a signed byte or not. (It is declared as 'char' in C++ struct definition)

UPD: Does It depends on whether C++ lib was build with GCC or VS (default compiler options)? If not, can I hope 'char' is signed on both GCC and VS (default compiler options)

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

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

发布评论

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

评论(3

知你几分 2024-11-10 23:12:42

一般来说,您无法判断 C++ 中的 char 是有符号的还是无符号的。这取决于实现,并且通常可以通过选项配置单个编译器(实现)以实现任一方式。

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

You can't, in general, tell if char is signed or unsigned in C++. It depends on the implementation, and a single compiler (implementation) can often be configured through options to make it either way.

The best choice would be to make it explicit in the C++ code if possible, i.e. use signed char or unsigned char. Then you can pick sbyte or byte for the C# marshalling as appropriate.

烟燃烟灭 2024-11-10 23:12:42

在 Visual Studio 和 GCC 中,char默认签名/J 编译器选项 (-funsigned-char< /code> 对于 GCC)可用于使其未签名。

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

In Visual Studio and GCC, char is signed by default. The /J compiler option (-funsigned-char for GCC) can be used to make it unsigned.

So the answer depends on whether or not that option is used in your C++ project.

-黛色若梦 2024-11-10 23:12:42

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

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

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


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

The answer depends on how you prefer to store the value in C#. You should choose whichever is most convenient.

  • If you store it in your C# variable as an unsigned value, then marshal it as UnmanagedType.U1.
  • If you store it in your C# variable as a signed value, then marshal it as UnmanagedType.I1.

The point being that once that byte crosses the module boundary it's the bitwise representation that matters and not the logical representation in the C# code. An unsigned value of 255 is equivalent to a signed value of -1 once you have reached the C++ code.


Of course, this assumes that you are using char as a character type. In a comment to the question you state that you are using it as a integer type, in which case you need to decide whether or not it is signed and marshal accordingly.

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