小编Shl*_*itz的帖子

固定缓冲区与使用“MarshalAs”属性和“UnmanagedType.ByValArray”之间有什么区别?

嗯,有一些明显的区别:
固定缓冲区:

  • 它们必须在 unsafe 块中声明(意味着整个项目必须使用-unsafeswitch 进行编译)。
  • 为了使用固定缓冲区,包含的对象必须是固定的,

使用MarshalAs属性:

  • 尽管大小已提供给编组器,但不能保证实际数组具有足够的元素计数,也不能保证它不为空。
  • 该数组可以像任何其他数组一样简单直观地使用。

但我找不到答案,为什么首先需要固定缓冲区?
什么时候必须使用它们?
假设可以验证常规托管数组的大小,为什么要使用它?

我可以想到性能限制,这可能会让人们选择固定缓冲区而不是常规数组......
仅此而已吗?

提前致谢。

c# pinvoke

5
推荐指数
1
解决办法
429
查看次数

C#中有趣的类型系统违规(在安全的环境中)

我谈到的类型系统违规 - 是在模仿工会时.

为什么在安全的环境中允许它?

  • 它允许您处理值类型,作为不同的值类型 - 就像您将实现的那样:

    float f = 2.5f;
    int binaryIdenticalInt =*((int*)&f);

  • 它允许您引用类型为X的对象,因为它是Y类型,即使这些类型之间没有关系.

  • 它允许您创建CLR甚至不会加载的类型(如果至少有一个重叠字段是引用类型,并且其中至少有一个是值/指针类型 - CLR将拒绝加载它).我希望C#编译器比它允许的内容更加挑剔,而不是CLR.不低于.

那么,为什么编译器首先在安全的上下文中允许这样的东西呢?为什么它不需要具有显式布局的类型的不安全上下文,它们具有重叠的字段?

我希望那里有人有答案 - 因为它必须有趣.

示例(所有编译都没有不安全的块,甚至不安全的开关):

[StructLayout(LayoutKind.Explicit)]
struct ValueUnion
{
    [FieldOffset(0)]
    public int i;

    [FieldOffset(0)]
    public float f;
}

[StructLayout(LayoutKind.Explicit)]
struct ReferenceUnion
{
    [FieldOffset(0)]
    public string str;

    [FieldOffset(0)]
    public Stream stream;
}

[StructLayout(LayoutKind.Explicit)]
struct CLRWontLoad
{
    [FieldOffset(0)]
    public string str;

    [FieldOffset(0)]
    public IntPtr ptr;
}
Run Code Online (Sandbox Code Playgroud)

.net c#

2
推荐指数
1
解决办法
503
查看次数

标签 统计

c# ×2

.net ×1

pinvoke ×1