【问题标题】:How to write directly to memory in C#如何在 C# 中直接写入内存
【发布时间】:2020-04-13 22:59:47
【问题描述】:

我正在做一个串口通讯项目。有一个硬件发送带符号的 16 位整数值,这些值被接收到 C# PC 应用程序中。 每个值通过两个字节发送,最低有效字节在前。

性能至关重要,因此我正在寻找减少处理的方法。

C# Serial Port 对象提供了一个方法 ReadExisting,它将当前缓冲的值作为字符串返回。 它还提供了一个 Read 方法,它可以接受一个字节数组,然后用端口缓冲区中的字节填充该数组。

如果我将所有值读入一个字节数组,我必须将两个字节连接在一起以获得 16 位数字。

我对从 ReadExisting 方法返回的字符串很感兴趣。 如果我创建一个短数组(short [] MyValues),然后我可以获取数组的内存位置,并将字符串写入该位置。只要我确保字节以正确的顺序发送,我就可以在需要时简单地读取 16 位值。

或者,我可以可能创建两个数组,一个是短裤数组,第二个是字节数组,大小是第一个的两倍,两者都具有相同的内存位置。

但是,“这里有龙”。我对 C# 和这种级别的内存访问没有经验。 一些简短的谷歌搜索表明这是可能的——这篇文章有一些有趣的信息: https://www.developerfusion.com/article/84519/mastering-structs-in-c/

在我进入这个特殊的兔子洞之前,是否有人对如何实现这种级别的内存操作有任何建议?

谢谢

【问题讨论】:

  • 使用带有覆盖层的结构。覆盖可以允许在 byte[] 和 int16[] 中读取/写入。
  • @jdweng,只有在处理器是 little-endian 时才有效
  • 你可能需要pin你的数据块。
  • @JimRhodes C# 项目已经有 15 个月了,所以不能切换。 C# 项目基于 WPF,因此只能在 W7/8/10 上运行。全部基于 X86,因此字节顺序不是问题。
  • 瓶颈不是字节数组到整数数组的转换。你在做一个毫无意义的优化。

标签: c# serial-port


【解决方案1】:

尝试叠加

       static void Main(string[] args)
        {
            const int NUMBER_OF_BYTES = 100;
            ByteInt16 byteInt = new ByteInt16();
            byteInt.data = new byte[NUMBER_OF_BYTES];
            byteInt.data2 = new UInt16[NUMBER_OF_BYTES / 2];

            byteInt.data = Enumerable.Range(0, NUMBER_OF_BYTES).Select(x => (byte)x).ToArray();

            UInt16[] results = byteInt.data2.Select(x => (UInt16)x).ToArray();

        }

        [StructLayout(LayoutKind.Explicit)]
        public struct ByteInt16
        {
            [FieldOffset(0)]
            public byte[] data;
            [FieldOffset(0)]
            public UInt16[] data2;
        }

【讨论】:

  • 只能叠加简单类型,如int、double等,不能叠加数组。
  • @David Heffernan:我最近做了很多,它适用于数组,但是在使用之前,您必须为覆盖中的每个项目调用构造函数(带有大小)。一旦设置好尺寸,就可以完美运行。
  • 不,你没有。如果您确实这样做了,那么您遇到了运行时,因为封送拆收器未能处理它无法封送的类型。
  • 这没有考虑处理器的字节顺序,因此不应被视为可接受的解决方案。
  • @jdweng 为什么不调试你的程序,看看长度不是你想的那样。真是一团糟。
猜你喜欢
  • 2011-12-03
  • 1970-01-01
  • 2010-11-28
  • 1970-01-01
  • 2011-01-21
  • 2023-03-13
  • 1970-01-01
  • 2015-07-27
相关资源
最近更新 更多