- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在对 System.Runtime.CompilerServices.Unsafe
MSIL 包进行一些极其不安全且略微无用的操作,它允许您使用指针做很多在 C# 中做不到的事情。我创建了一个返回 ref byte
的扩展方法,该字节是对象开始处方法表指针的开始,它允许您在固定语句中使用任何对象,采用指向对象开始的字节指针:
public static unsafe ref byte GetPinnableReference(this object obj)
{
return ref *(byte*)*(void**)Unsafe.AsPointer(ref obj);
}
然后我决定使用以下代码对其进行测试:
[StructLayout(LayoutKind.Explicit, Pack = 0)]
public class Foo
{
[FieldOffset(0)]
public string Name = "THIS IS A STRING";
}
[StructLayout(LayoutKind.Explicit, Pack = 0)]
public struct Bar
{
[FieldOffset(0)]
public string Name;
}
然后在方法中
var foo = new Foo();
//var foo = new Bar { Name = "THIS IS A STRING" };
fixed (byte* objPtr = foo)
{
char* stringPtr = (char*)(objPtr + (foo is Foo ? : 12));
for (var i = 0; i < foo.Name.Length; i++)
{
Console.Write(*(stringPtr + i /* Char offset */));
}
Console.WriteLine();
}
Console.ReadKey();
真正奇怪的是它成功打印了“THIS IS A STRING”?代码是这样工作的:
objPtr
int
_stringLength
(作为 Length
属性向我们公开)编辑:重要的一点 - 当将 foo
切换为键入 Bar
时,我只添加了 12 个字节而不是 36 个字节 (36 = 16 + 16 + 4)。为什么它在结构中只有 8 个字节的 header 而不是类中的 32 个?该结构具有较小的 header (我相信没有 syncblk)是有道理的,但是为什么字符串仍然没有 16 字节的 header ?我希望偏移量为 8 + 16 + 4 (28) 而不仅仅是 8 + 4 (12)然而,这种假设存在很大的缺陷。它假定字符串以内联方式存储在 class/struct
中。但是,字符串是引用类型,据我所知,只有对它们的引用存储在对象内部。特别是,我认为引用类型只能放在堆上——因为这个结构是一个局部变量,我认为它在堆栈上。如果不是,代码肯定看起来更像这样来获取 stringPtr
byte** stringRefptr = objPtr + 16;
char* stringPtr = (char*)(*stringRefPtr + 20);
将字符串引用作为 byte**
,然后使用它来获取字符。如果字符串内部是 char[]
(我不确定它是否是)
那么,当字符串是引用类型时,为什么它会工作并打印字符串,即使它错误地假设字符串是内联存储的?
注意:需要 .NET Core 2.0+ 和 System.Runtime.CompilerServices.Unsafe
nuGet 包,以及 C# 7.3+。
最佳答案
因为字符串确实是内联存储的。您假设的问题是字符串不是普通对象,而是作为特殊情况由 CLR 处理(可能出于性能原因)。
至于对象,由于字符串是唯一的成员,这自然是分配内存的最有效方式。尝试在您的字符串成员之后添加更多成员,您的代码将会中断。
这里有一些关于字符串如何存储在 CLR 中的引用资料
https://mattwarren.org/2016/05/31/Strings-and-the-CLR-a-Special-Relationship/
https://codeblog.jonskeet.uk/2011/04/05/of-memory-and-strings/
编辑:我没有检查,但我相信你在偏移量背后的推理是错误的。 36 = 24(对象的大小)+ 8(字符串标题?)+ 4(整数的大小),而对于结构,24 个字节变为 0,因为它没有标题。
关于c# - 为什么看起来这个字符串是按值内联存储在显式布局类或结构中的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54060690/
#include #include #include using namespace std::chrono; int main(int arc, char* argv[]) { con
我是 opencv 的新手。当我将 sRGB png 提供给它时,我发现以下代码交换了红色和蓝色 channel 。我应该责怪哪个函数,imread 还是 fromarray? 最佳答案 是的,O
我正在使用以下代码,它缩小了每一行,并且由于某种原因整个用户界面也丢失了。我该如何解决?
它是关于以下设置的:Linux 机器、bash、adb、带有 Busybox 的嵌入式 Linux 目标系统。对于目标系统,以下适用: adb shell echo $SHELL /bin/sh ad
当我在 Android Studio 上创建一个空 fragment 时,它会生成以下代码: /** * A simple {@link Fragment} subclass. * Activit
我正在尝试从 Meteor 应用程序的服务器端发布用户的 Facebook 提要: result = Meteor.http.call 'POST', "https://graph.faceb
目前我有两个不同的查询,它们返回完全相同的结果,但是,更改从中过滤结果的参数会使它们以非常不同的方式运行。 搜索 cartography 时的结果 查询 #1: 22 行/~860 毫秒; SELEC
我已经创建了结构: typedef struct { short s; int i; struct Ss { short s; }; } S;
我想在 Java 中打印反斜杠 t。但每当我尝试时,它实际上都将它作为\t 运算符。双反斜杠不起作用。我该怎么做。 最佳答案 例如通过添加另一个反斜杠来转义反斜杠 System.out.println
我想弄清楚为什么 UIActivityViewController 发送一个稍微转换过的字符串来分享给邮件和微信。 这是我的代码: let activityViewController = UIAct
创建标准 SQLite 游标后,我将使用以下方法遍历条目: while (cursor.moveToNext()) { } 所有行都被正确处理。我读过的所有文档都表明您需要发出 moveToFirst
我正在尝试创建一个基本论坛,但在 SQL 中仅打印一行时遇到问题。这是我的 PHP: {$title}"; } } else { print "failed to reach post
我的新 div 元素 ( ) 似乎隐藏在图像后面。我键入的任何内容都显示在图像后面。我想在背景图片之后继续工作。 这是我的代码: DISPLAY
UPD。一行代码解决了问题:.lean() axplanation here 我在 Model.find(...blablabla : [ {"_id":"578763de6e8e0542195ef4
我在 Ubuntu 16.04 中安装了 Tomcat 8.0.45。我使用 let's encrypt 生成的证书启用了 HTTPS 连接器。它就像一个魅力。但是今天Tomcat无法启动HTTPS连
今天,我在一台全新安装了 Windows 7 Ultimate 64 位的新笔记本电脑上安装了 Visual Studio 2010 Professional。我非常习惯于 Visual Studio
根据 Oracle,我应该能够将 .intValue() 和 .compareTo() 之类的方法应用于 double ,但是当我编写 dbl.toString( ) 例如,在 NetBeans 中,
正在为应用程序开发一些拖放功能,虽然可以使用“重影图像”来完成很多事情,将毒品从一个地方转移到另一个地方,但它们看起来总是有点“褪色” - 因此得名鬼影。是否有可能使这些具有与原始颜色相同的深度?谢谢
我是这方面的新手,很抱歉犯了一些愚蠢的错误。快乐学习。每当我使用 URL : localhost:3000/posts/whatever 时,我都会收到无法获取错误。在你问之前,是的,那是在我将内容放
背景 这自然是合法的: let closure: (Int, Int) -> () = { print($0 + $1) } closure(1, 2) // 3 鉴于,自进化提案实现以来 SE-01
我是一名优秀的程序员,十分优秀!