【问题标题】:How to get fixed buffer length?如何获得固定的缓冲区长度?
【发布时间】:2016-05-09 17:07:35
【问题描述】:

有没有办法获取固定大小缓冲区的长度?

类似:

public struct MyStruct
{
    public unsafe fixed byte buffer[100];

    public int foo()
    {
        return sizeof(buffer); // Compile error.
    }
}

有没有办法完成这样的事情?

【问题讨论】:

  • 为什么不定义一个像 const int BUFFER_SIZE = 100 这样的常量,然后使用 buffer[BUFFER_SIZE]。这运行速度更快,分配由编译器完成。
  • 因为这会给我的结构增加一些不必要的冗长。我的代码会有很多这样的结构。有什么想法吗?谢谢。
  • 这比在每个结构中放一个方法 foo 的代码要少很多。
  • 但是我不打算创建那个 foo 方法,我只是写来澄清事情和概念:(

标签: c# pointers sizeof fixed unsafe


【解决方案1】:

在 C++ 中 like,您必须保持内置数组的大小。这同样适用于 C# 中的固定缓冲区。这种类型是comparableinline_array。这为您带来了诸如静态代码检查之类的好处。因为它们不是 C# 的一流特性,所以使用它们有点麻烦。所以可能最好的解决方案是将大小作为结构的一部分。您可能只需要处理它或使用集合/C# 的System.Array。也许另一种解决方案是将固定缓冲区创建为单独的结构,然后将其与其他数据一起作为另一个结构的一部分。

【讨论】:

  • 好的,考虑到这是更接近的答案,我会接受。不幸的是,当更深入的互操作开始发挥作用时,c# 表现出非常有限:/
  • “在 C++ 中,你必须保持内置数组的大小”是不正确的。 (sizeof array)/(sizeof *array) 适用于内置数组,包括具有数组类型的结构/类数据成员。或者您可以使用非类型模板参数的推断。您链接到有关查找指针指向的动态内存范围大小的讨论,这根本不是问题中的 C# 代码中发生的事情。
【解决方案2】:

好吧,我迟到了 6 年才回答,但我做到了。显然有一个包含固定缓冲区长度的属性!这是一个简单的方法来获得它。您需要传递 MyStruct 类型和字段名称:

    public static int GetFixedBufferSize(Type type, string field)
    {
        FieldInfo fi = type.GetField(field);
        object[] attrs = fi.GetCustomAttributes(typeof(FixedBufferAttribute), false);
        if (attribs != null && attribs.Length != 0)
        {
            FixedBufferAttribute attr = (FixedBufferAttribute)attribs[0];
            Console.WriteLine($"{attr.ElementType.Name} {field}[{attr.Length}]");
            return attr.Length;
        };

        throw new Exception("Not a FixedBuffer");
    }

希望这对你有用,我用你的例子试过了,它成功了!

【讨论】:

  • 这是否依赖于反射?您要根据名称作为运行时变量字符串来请求字段吗?当然,这并不快,因此如果出于性能原因使用unsafe fixed 数组,则不希望在普通代码中使用它。
【解决方案3】:

这是一个数组;你可以使用.Length

【讨论】:

  • 固定大小的缓冲区不是数组。长度是 System.Array 的一个属性,因此我无法访问它:(
  • 也许@MartinCostello,你能告诉我如何在固定缓冲区中使用 Marshal.SizeOf 吗?谢谢。
  • 你可以试试这些:return Marshal.SizeOf(this);return Marshal.SizeOf(typeof(MyStruct));return Marshal.SizeOf(buffer);
  • 在我的情况下,这些都不起作用@MartinCostello。 MyStruct 将包含其他类型, SizeOf(typeof(MyStruct)) 将返回整个结构的编组大小,并且 SizeOf(buffer) 不编译。 SizeOf 需要一个类型。
  • @MartinCostello:不;只是fixed 很奇怪。我不确定这是否可能(!)。玩tryroslyn.azurewebsites.net/#f:s/…
猜你喜欢
  • 2011-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-17
相关资源
最近更新 更多