问题标签 [layoutkind.explicit]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c# - 如何在 C# 中将固定字节/字符 [100] 转换为托管字符 []?
在 C# 中将固定字节或 char[100] 转换为托管 char[] 的最佳方法是什么?我最终不得不使用指针算法,我想知道是否有更简单的方法——比如 memcpy 或其他方法?
c# - 带有 LayoutKind.Explicit 的布尔编组,这是按设计破坏还是失败?
首先,Boolean 类型据说有一个四字节值的默认 marshal 类型。所以下面的代码有效:
显然,这些结构独立编组就好了。这些值按预期翻译。然而,当我们通过像这样声明 LayoutKind.Explicit 将这些结构组合成一个“联合”时:
我们突然发现自己无法正确编组这些类型。这是上述结构的测试代码以及它是如何失败的:
把这个表达式看成真的很幽默:(a.bValue1 != false && a.bValue1 == true && !true.Equals(a.bValue1))
当然,这里更大的问题是 a.iValue2 != 4,而不是 4 已更改为 1(可能是重叠的布尔值)。
所以问题是:这是一个错误,还是按设计失败了?
背景:这来自 使用 PInvoke 时包含 bool 与 uint 的结构有什么区别?
更新:当您使用大整数值(> 255)时,这甚至更奇怪,因为只有用于布尔值的字节被修改为 1,因此将 b.bValue2 的 0x0f00 更改为 0x0f01。对于上面的 a.bValue1,它根本不翻译,0x0f00 为 a.bValue1 提供了一个错误值。
更新#2:
对上述问题最明显和最合理的解决方案是使用 uint 进行编组并改为公开布尔属性。用“变通方法”真正解决问题是没有问题的。我最想知道这是一个错误还是您所期望的行为?
c# - 在 Release 构建中编组具有重叠的 LayoutKind.Explicit 结构失败
我有一个结构,它有一个报告为重叠的非重叠字段。
报告的错误是:
无法加载类型“XXX”...它包含偏移 12 处的对象字段,该对象字段未正确对齐或被非对象字段重叠。
它只发生在发布配置中(启用了跟踪、调试标志和不安全代码,关闭了优化),猜测 - 它会发生什么?
UPD:感谢@svick。确认 x64 构建不是人们想要的编组。
mono - 为什么 atmel 处理器上的单声道不能很好地与 LayoutKind.Explicit 配合使用?
我创建了一个如下结构:
然后我用下面的代码阅读了它:
我想知道在 x86、x64 和 cortex arm 处理器中一切正常,但在 Atmel ARM9 AT91SAM9G20 上的ushort
变量我得到了错误的值,例如第一个和第三个下一个字节值替换而不是第一个和第二个下一个字节,但是对于字节值一切都很好
c# - LayoutKind.explicit 对于本身是结构的字段的 .NET 行为
问题
我尝试SA
使用 构建一个结构 () [StructLayout(LayoutKind.Explicit)]
,它有一个字段是另一个struct
( SB
)。
首先:我很惊讶我被允许声明其他结构没有[StructLayout(LayoutKind.Explicit)]
,而在 中SA
,所有字段都必须有[FieldOffset(0)]
,否则编译器会大喊大叫。这没有多大意义。
- 这是编译器警告/错误中的漏洞吗?
第二:好像把里面的所有reference( object
)字段SB
都移到了前面SB
。
- 这种行为在任何地方都有描述吗?
- 它依赖于实现吗?
- 它是否在任何依赖于实现的地方定义?
:)
注意:我不打算在生产代码中使用它。我问这个问题主要是出于好奇。
实验
c# - 子结构具有 LayoutKind.Explicit 时不遵循 LayoutKind.Sequential
运行此代码时:
我希望在 x86 和 x64 上都有这个输出:
4 或 8(取决于 x86 或 x64)
2
3
1
6
0
4
5
垃圾
我在 x86 上得到的是:
4
6
0
2
3
1
4
5
垃圾
我在 x64 上得到的是:
8
6
0
2
3
1
0
4
5
更多:
- 当我删除 LayoutKind.Explicit 和 FieldOffset 属性时,问题就消失了。
- 当我删除 Bool 字段时,问题就消失了。
- 当我删除长字段时,问题就消失了。
- 请注意,在 x64 上似乎 Pack=4 属性参数也被忽略了?
这适用于 .Net3.5 和 .Net4.0
我的问题:我错过了什么?或者这是一个错误?
我发现了一个类似的问题:
如果结构包含 DateTime 字段,为什么 LayoutKind.Sequential 的工作方式会有所不同?
但在我的情况下,即使子结构的属性发生变化,布局也会发生变化,而数据类型没有任何变化。所以它看起来不像是优化。除此之外,我想指出,另一个问题仍未得到解答。
在另一个问题中,他们提到使用编组时尊重布局。我自己还没有测试过,但我想知道为什么布局不尊重不安全代码,因为所有相关属性似乎都已经到位?文档是否在某处提到除非完成编组,否则这些属性将被忽略?为什么?
考虑到这一点,我什至可以期望 LayoutKind.Explicit 能够可靠地处理不安全的代码吗?
此外,文档提到了保持结构与预期布局的动机:
为了减少与 Auto 值相关的布局相关问题,C#、Visual Basic 和 C++ 编译器为值类型指定了顺序布局。
但是这个动机显然不适用于不安全的代码?
c# - 使用 LayoutKind.Explicit 来绕过使用“不安全”指针是否合法?
我有使用指针对数据块进行异或的代码,这很快,但我想摆脱对程序集的“不安全”要求。如果我将其更改为使用 LayoutKind.Explicit 并在“byte []”之上覆盖“ulong []”,我基本上会做与指针相同的事情,但它似乎同样危险。这两者的主要区别在于“安全”版本的速度大约是“不安全”版本的 1/2。
这是解决“不安全”程序集的合法方式,还是一次访问 byte[] 1 个字节是以安全方式执行此操作的唯一合法方式?
c# - Union in C# with string incorrectly aligned
I am having "Incorrectly aligned or overlapped by non-object field" error with the following code.
I implemented union by using System.Runtime.InteropServices with LayoutKind.Explicit
I think the issue comes from string in the struct. How do I overcome this problem?
c# - Exclude extra private field in struct with LayoutKind.Explicit from being part of the structure layout
Let's say we have one structure :
What I want to have : Both direct access to type string
and int
values, for the field Ident
in this structure, without breaking the 8 bytes size of the structure, nor having to compute a string value each time from the int value.
The field Ident
in that structure as int
is interesting because I can fast compare with other idents if they match, other idents may come from datas that are unrelated to this structure, but are in the same int
format.
Question : Is there a way to define a field that is not part of the struture layout ? Like :
PS : I use pointers ('*' and '&', unsafe) because I need to deal with endianness (Local system, binary files/file format, network) and fast type conversions, fast arrays filling. I also use many flavours of Marshal
methods (fixing structures on byte arrays), and a little of PInvoke and COM interop. Too bad some assemblies I'm dealing with doesn't have their dotNet counterpart yet.
TL;DR; For details only
The question is all it is about, I just don't know the answer. The following should answer most questions like "other approaches", or "why not do this instead", but could be ignored as the answer would be straightforward. Anyway, I preemptively put everything so it's clear from the start what am I trying to do. :)
Options/Workaround I'm currently using (or thinking of using) :
Create a getter (not a field) that computes the string value each time :
This approach, while doing the job, performs poorly : The GUI displays aircraft from a database of default flights, and injects other flights from the network with a refresh rate of one second (I should increase that to 5 seconds). I have around 1200 flights within a area, relating to 2400 airports (departure and arrival), meaning I have 2400 calls to the above code each second to display the ident in a DataGrid.
Create another struct (or class), which only purpose is to manage data on GUI side, when not reading/writing to a stream or file. That means, read the data with the explicit layout struct. Create another struct with the string version of the field. Work with GUI. That will perform better on an overall point of view, but, in the process of defining structures for the game binaries, I'm already at 143 structures of the kind (just with older versions of the game datas; there are a bunch I didn't write yet, and I plan to add structures for the newest datas types). ATM, more than half of them require one or more extra fields to be of meaningful use. It's okay if I were the only one to use the assembly, but other users will probably get lost with
AirportHeader
,AirportHeaderEx
,AirportEntry
,AirportEntryEx
,AirportCoords
,AirportCoordsEx
.... I would avoid doing that.Optimize option 1 to make computations perform faster (thanks to SO, there are a bunch of ideas to look for - currently working on the idea). For the Ident field, I guess I could use pointers (and I will). Already doing it for fields I must display in little endian and read/write in big endian. There are other values, like 4x4 grid informations that are packed in a single Int64 (ulong), that needs bit shifting to expose the actual values. Same for GUIDs or objects pitch/bank/yaw.
Try to take advantage of overlapping fields (on study). That would work for GUIDs. Perhaps it may work for the Ident example, if MarshalAs can constrain the value to an ASCII string. Then I just need to specify the same FieldOffset, '0' in this case. But I'm unsure setting the field value (
entry.FieldStr = "FMEP";
) actually uses the Marshal constrain on the managed code side. My undestanding is it will store the string in Unicode on managed side (?). Furthermore, that wouldn't work for packed bits (bytes that contains several values, or consecutive bytes hosting values that have to be bit shifted). I believe it is impossible to specify value position, length and format at bit level.
Why bother ? context :
I'm defining a bunch of structures to parse binary datas from array of bytes (IO.File.ReadAllBytes) or streams, and write them back, datas related to a game. Application logic should use the structures to quickly access and manipulate the datas on demand. Assembly expected capabilities is read, validate, edit, create and write, outside the scope of the game (addon building, control) and inside the scope of the game (API, live modding or monitoring). Other purpose is to understand the content of binaries (hex) and make use of that understanding to build what's missing in the game.
The purpose of the assembly is to provide a ready to use basis components for a c# addon contributor (I don't plan to make the code portable). Creating applications for the game or processing addon from source to compilation into game binaries. It's nice to have a class that loads the entire content of a file in memory, but some context require you to not do that, and only retrieve from the file what is necessary, hence the choice of the struct pattern.
I need to figure out the trust and legal issues (copyrighted data) but that's outside the scope of the main concern. If that matter, Microsoft did provide over the years public freely accessible SDKs exposing binaries structures on previous versions of the game, for the purpose of what I'm doing (I'm not the first and probably not the last to do so). Though, I wouldn't dare to expose undocumented binaries (for the latest game datas for instance), nor facilitate a copyright breach on copyrighted materials/binaries.
I'm just asking confirmation if there is a way or not to have private fields not being part of the structure layout. Naive belief ATM is "that's impossible, but there are workarounds". It's just that my c# experience is pretty sparce, so maybe I'm wrong, why I ask. Thanks !
As suggested, there are several ways to get the job done. Here are the getters/setters I came up with within the structure. I'll measure how each code performs on various scenarios later. The dict approach is very seducing as on many scenarios, I would need a directly accessible global database of (59000) airports with runways and parking spots (not just the Ident), but a fast check between struct fields is also interesting.