带 char 的 Marshall 结构
将包含单个 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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
一般来说,您无法判断 C++ 中的
char
是有符号的还是无符号的。这取决于实现,并且通常可以通过选项配置单个编译器(实现)以实现任一方式。如果可能的话,最好的选择是在 C++ 代码中明确显示,即使用
signed char
或unsigned char
。然后,您可以根据需要选择sbyte
或byte
进行 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
orunsigned char
. Then you can picksbyte
orbyte
for the C# marshalling as appropriate.在 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.
答案取决于您喜欢如何在 C# 中存储该值。您应该选择最方便的。
UnmanagementType.U1
。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.
UnmanagedType.U1
.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.