C#中,tagRECT结构的成员top、right、left、bottom代表啥?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#中,tagRECT结构的成员top、right、left、bottom代表啥?相关的知识,希望对你有一定的参考价值。

据说其中left、top表示矩形左上角的x、y坐标值,right、bottom表示矩形右下角的x、y坐标值。那代表的坐标值是屏幕坐标系统下的(左上方为原点),还是地图数据的地理坐标系统下的?是以像素为单位计量,还是以距离单位计量的?

这个是vc或者windows编程的下的结构也就是RECT结构体,用过的人都该清楚,是屏幕左上为原点,它的单位当然是像素了,这个最好去查MSDN的vc下的RECT 参考技术A 这根地理坐标系是两码事儿吧,完全是两个概念啊 参考技术B 这个跟vC中的rect结构体是一样的

C# struct 或 struct[] 作为内存中连续结构的成员

【中文标题】C# struct 或 struct[] 作为内存中连续结构的成员【英文标题】:C# struct or struct[] as member of struct contiguous in memory 【发布时间】:2021-06-30 10:49:06 【问题描述】:

我试图了解如何将结构作为结构的成员存储在内存中。据我了解,如果我们在内存中有一个简单的结构,例如

struct Simple 
  int x;
  bool y;

如果我们在内存中初始化Simple s = new Simple(),我们会看到类似的连续内容

s(0x01) --> 0x01(x - 32 bits data, y - 32 bits data) 

所以如果我们调用s.x,那么我们需要将s 提取到cpu 中,然后可以访问x 和y 进行操作,因为它们是连续的。

现在,如果我们有一个结构数组作为成员

struct Simple 
  int x;
  Other[] otherArray;

  Simple(int input, Other[] otherInput)
  
    x = input;
    otherArray = otherInput;
  


struct Other 
  bool y;

如果我们做了Simple s = new Simple(),那么在内存中我们会有

s(0x01) --> 0x01(x - 32 bits, otherArray - 64 bit reference type) 

s.otherArray[0] 需要单独获取,无论它存储在内存中的何处。这是因为otherArray 中的实际值不与x 连续存储,但对数据的引用在x 之后是连续的。如果otherArray 被初始化为Simple s = new Simple(1, new Simple[1]),那么otherArray 数据会在x 之后连续存储还是otherArray 始终是引用类型(无论它是否在结构构造函数中初始化)?

最后,如果我们有一个结构体作为结构体的成员

struct Simple 
  int x;
  Other other;

这是我不清楚的地方。 Simple s = new Simple() 现在是否存储为

s(0x01) --> 0x01(x - 32 bits data, other - 32 bits data of y as bool)

是吗

s(0x01) --> 0x01(x - 32 bits, other - some reference to the data containing y as bool)

换句话说,一个结构体是作为结构体的成员与结构体连续存储,还是简单地存储为另一个结构体实际数据的某种地址?

我也希望能更正我的逻辑或进一步了解不同类型如何存储在 struct 中的内存中,因为我试图大致了解 C# 如何在内存中存储数据,谢谢

【问题讨论】:

Other 是指向其余数据所在位置的指针。在 c# 中,结构被包装,因为 c# 被管理以防止在找到空地址时出现异常。在直接的 c 语言中,没有包装器,所以 other 是一个指针,但可能是 other 后面的地址。 c# 中的包装器作为您看不到的其他内部字节。 @jdweng 真的吗?我通过使用Marshal.ReadInt64 阅读结构的内容发现了相反的结果。另一个观察结果是,当Other 的大小增长时,Simple 的大小也会增长。 SharpLab 的Inspect.Stack 将它们显示为一个连续的组合对象。并且Unsafe.SizeOf 适当增加/减少。看到这个sharplab(并取消注释两行注释)sharplab.io/… @Sweeper :您是否验证了使用 sizeof() 观察到的内容? @jdweng 是的,它表明other 不是指针。 【参考方案1】:

otherArray 数据是否会在x 之后连续存储,或者otherArray 始终是引用类型

otherArray 始终是一个数组对象的引用,即使它只有一个元素。结构布局是结构类型的属性,而不是特定结构值的属性。

是作为结构成员的结构与结构连续存储还是简单地存储为其他结构的实际数据的某种地址?

结构是值类型,因此没有“其他结构的实际数据的某种地址”。这就是引用类型的作用。它不一定是连续的,(但在OtherSimple 的情况下是连续的) - 如果您没有明确指定PackLayoutKind,它将遵循默认对齐规则。请参阅here 了解更多信息。

让我们考虑一下:

struct Simple

    public int x;
    public Other other;


struct Other

    public int y;

和价值:

var s = new Simple();
s.x = unchecked((int)0xabcdefab);
s.other.y = 0x12345678;

您希望s 的大小为8 字节,其值将包含数字0xabcdefab0x12345678

// prints 8
Console.WriteLine(sizeof(Simple));
// in an unsafe block, prints 12345678ABCDEFAB
Console.WriteLine(Marshal.ReadInt64(new IntPtr(&s)).ToString("X"));

您可以尝试向Other 添加更多字段,并看到sizeof(Simple) 增加

将此与引用类型进行比较:

struct Simple

    public int x;
    public OtherRef other;


class OtherRef

    public int y;

您现在不能使用& 获取地址,所以这里有一个sharplab 链接,表明other 字段确实是一个地址,而不是您设置的值。

【讨论】:

以上是关于C#中,tagRECT结构的成员top、right、left、bottom代表啥?的主要内容,如果未能解决你的问题,请参考以下文章

C#:循环遍历嵌套结构的成员对象

Forward团队-爬虫豆瓣top250项目-成员简介与分工

Unity 2D Top Down Shooter 运动问题 C#

c# 在类嵌套结构中引用非静态类成员

C# 中结构的实例和成员的堆和堆栈如何工作?

将具有枚举成员的非托管结构编组到 c#