c# - 在 C# 中容纳嵌套的不安全结构

标签 c# c++ c struct unsafe

适应以下情况的最佳方式是什么:

实时、性能关键的应用程序,与 native C dll 接口(interface)以与专有后端通信。

native api 有成百上千的结构、嵌套结构和通过这些结构来回传递数据的方法。

想将 c# 用于逻辑,因此决定使用不安全的 c# 以支持 cli 和编码(marshal)处理。我知道如何并且已经通过后者实现了这一点,所以请不要回复“使用 cli”。每秒编码(marshal)数百个结构一百次会引入足够大的延迟,因此有必要调查不安全的 c#。

大多数 c 结构包含许多字段,因此正在寻找一种方法来对每个字段进行最少的键入。在这一点上,在必要时运行 VS 宏将每个行元素转换为 c# 等效设置数组以固定大小。在我遇到嵌套的结构数组之前,这个工作非常好。例如,我有这两个结构:

[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]
}

容纳固定 User 用户[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]
}

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

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

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

第三种方法让我难以理解以至于我无法制作和示例(我想我在某处看到但再也找不到它)是为用户指定大小或以某种方式严格调整大小以便您可以使用“fixed”关键字。

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

最佳答案

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

[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 是没有问题的。或者,这可以包装在另一个进行存储的托管对象中。

关于c# - 在 C# 中容纳嵌套的不安全结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19168658/

相关文章:

c++ - 没有 CDDS_ITEMPREPAINT 阶段的颜色 CListCtrl 列背景

c++ - 有人提出为什么我的代码在 basic_ios 和 sstream 中产生错误吗?

c - pthread_cond_signal() 中的段错误

c - recvfrom 在信号后不返回-1

c# - monodroid中Task的实现

c# - ASP.NET/C# : DropDownList SelectedIndexChanged event not firing

c# - Swagger codegen 选项可更改 TypeScript 中的大小写

c++ - 以 x y z r g b 格式读取 ascii 点云

c# - DTO 上的 ASP.Net Web API 验证属性?

c - 如何从参数行获取数字?