将大量数据从Rust FFI库返回给C#caller的最快方法是什么?

将大量数据从Rust FFI库返回给C#caller的最快方法是什么?,c#,serialization,rust,dllimport,ffi,C#,Serialization,Rust,Dllimport,Ffi,我正在.NET C#中开发一个程序,使用extern C关键字并由DllImport加载,通过Rust FFI调用我自己的Rust库 我这样做是因为我想把复杂的计算委托给Rust。从Rust库进行处理后,预计会将大量数据返回到C#。在C#中使用这些数据时,这些数据应该在一种列表中 那么我的问题是: 从Rust开始,传回这些数据的最佳方式是什么?通过一个指向内存块的指针,内存块像结构数组一样排列 C#如何找回这样的内存块指针?这里有线程安全问题吗 如何在C#中快速将这样的数据存储块转换为我的列表

我正在.NET C#中开发一个程序,使用extern C关键字并由DllImport加载,通过Rust FFI调用我自己的Rust库

我这样做是因为我想把复杂的计算委托给Rust。从Rust库进行处理后,预计会将大量数据返回到C#。在C#中使用这些数据时,这些数据应该在一种
列表中

那么我的问题是:

  • 从Rust开始,传回这些数据的最佳方式是什么?通过一个指向内存块的指针,内存块像结构数组一样排列
  • C#如何找回这样的内存块指针?这里有线程安全问题吗
  • 如何在C#中快速将这样的数据存储块转换为我的
    列表

  • 我们需要回答的第一个问题是:谁将负责分配和释放内存?如果您事先知道将返回多少个元素,那么您可以让C代码或Rust代码分配内存。如果您事先不知道将返回多少个元素,那么您有两个选项:1)让C#代码询问锈代码将返回多少个元素(如果可能的话),然后从C#分配内存;2) 让代码分配内存。如果您从C#(例如托管阵列)分配托管内存,则可以让垃圾收集器释放内存。如果从C#或Rust分配非托管内存,则必须使用正确的函数释放内存。如果使用Rust的默认内存分配器,Rust代码将需要提供一个函数来释放内存。请记住,生成结果的Rust代码需要显式地“泄漏”数组/
    Vec
    ,否则函数将在返回前释放内存

    您会发现将.NET的
    列表
    类型与非托管代码一起使用很困难。您应该改为使用数组

    另一个重要的考虑因素是结构的布局。您必须将

    #[repr(C)]
    添加到Rust结构,并将
    [StructLayout(LayoutKind.Sequential)]
    [StructLayout(LayoutKind.Explicit)]
    (取决于结构内部的类型)添加到C结构,以确保结构的字段在内存中以相同的方式排列

    在C#代码中为Rust函数定义
    DllImport
    时,可以使用注释参数和返回值,以告知.NET运行时应如何封送或取消封送参数和返回值。特别是,
    LPArray
    成员在您的情况下可能会有所帮助,不过请注意。如果Rust代码负责分配内存,您还可以通过将指针定义为
    IntPtr
    并使用来解组结构并将指针偏移到下一个元素来手动执行解组。