适应 C# 中的嵌套不安全结构

本文关键字:不安全 结构 嵌套 适应 | 更新日期: 2023-09-27 18:33:44

适应

以下情况的最佳方法是什么:

实时、性能关键型应用程序,与本机 C dll 接口,以便与专有后端通信。

本机 api 有成百上千个结构、嵌套结构和方法,它们通过这些结构来回传递数据。

想要将 C# 用于逻辑,因此决定使用不安全的 C#,转而使用 CLI 和封送处理。我知道如何并通过稍后实现了这一点,所以请不要回复"使用 cli"。每秒封送数百个结构一百次会引入足够大的延迟,因此需要调查不安全的 C#。

大多数 c 结构包含数十个字段,因此正在寻找一种对每个字段进行最小键入的方法。此时,可以运行 VS 宏,以在必要时将每个行元素转换为 c# 等效的设置数组以固定大小。这工作得很好,直到我遇到嵌套结构数组。例如,我有以下 2 个结构:

[StructLayout(LayoutKind.Sequential,Pack=1)]
unsafe struct User{
    int id;
    fixed char name[12];
}
[StructLayout(LayoutKind.Sequential,Pack=1)]
unsafe structs UserGroup{
    fixed char name[12];
    fixed User users[512]
    int somethingElse;
    fixed char anotherThing[16]
}

容纳固定用户用户[512]的最佳方法是什么,以便在运行时不必做太多事情?

我见过建议要做的例子

[StructLayout(LayoutKind.Sequential,Pack=1)]
unsafe structs UserGroup{
    fixed char name[12];
    User users_1;
    User users_2;
    ...
    User users_511;
    int somethingElse;
    fixed char anotherThing[16]
}

另一个想法是,以字节为单位计算用户的大小并执行此操作

[StructLayout(LayoutKind.Sequential,Pack=1)]
unsafe structs UserGroup{
    fixed char name[12];
    fixed byte Users[28*512];
    int somethingElse;
    fixed char anotherThing[16]
}

但这意味着每次我需要使用它时,我都必须对这个结构进行特殊处理,或者用其他代码包装它。api中有足够的那些我想避免这种方法,但如果有人可以展示一种优雅的方式,我也可以工作

第三种方法让我无法生成和示例(我想我在某处看到但再也找不到了(,是为 User 指定大小或以某种方式使其严格大小,以便您可以在其上使用"固定"关键字。

任何人都可以推荐一种他们已经使用并在负载下很好地扩展的合理方法吗?

适应 C# 中的嵌套不安全结构

我可以在不

安全结构中找到嵌套结构的最佳方法是将它们定义为固定字节数组,然后为字段提供运行时转换属性。例如:

[StructLayout(LayoutKind.Sequential,Pack=1)]
unsafe struct UserGroup{
    fixed char name[12];
    fixed User users[512]
    int somethingElse;
    fixed char anotherThing[16]
}

变成:

[StructLayout(LayoutKind.Sequential,Pack=1)]
unsafe struct UserGroup{
    fixed char name[12];
    fixed byte users[512 * Constants.SizeOfUser]
    int somethingElse;
    fixed char anotherThing[16];
    public User[] Users
    {
        get
        {
            var retArr = new User[512];
            fixed(User* retArrRef = retArr){
                fixed(byte* usersFixed = users){
                    {
                        Memory.Copy(usersFixed, retArrRef,  512 * Constants.SizeOfUser);
                    }
                }
            }
            return retArr;
        }
    }
}

请注意,此代码使用此处提供的 Memory.Copy 函数:http://msdn.microsoft.com/en-us/library/aa664786(v=vs.71(.aspx

geter的一般解释如下:

  1. 为返回值分配托管数组
  2. 获取并修复指向它的不安全指针
  3. 获取并修复指向结构的字节数组的不安全指针
  4. 将内存从一个复制到另一个
托管

数组没有存储回它自己的结构中的原因是因为它会修改其布局并且不再正确转换,而从非托管获取时 prop 是没有问题的。或者,可以将其包装在执行存储的另一个托管对象中。