我需要从管理,过滤和分配数据的基于C / C ++的核心DLL中将大量(理论上高达几TB,仅受可用内存限制)的数据转移到C#GUI(其中只读取数据)。如果数据永远不会重复,但只能从C#的每个引用访问,那将是最佳的。我的DLL方法的签名目前如下(我可以在那里进行更改):
extern "C" {
typedef struct {
wchar_t* name;
__int32 t;
float v;
bool condition;
} TestData;
__declspec(dllexport) void fillTestArrayWithAlloc(TestData** td, __int32* size);
};
C#不知道数组长度,可以是1到数百万之间的任何数据....
我映射了这样的结构:
[StructLayout(LayoutKind.Sequential)]
struct TestData
{
[MarshalAs(UnmanagedType.LPWStr)]
public String name;
public Int32 t;
[MarshalAs(UnmanagedType.R4)]
public float v;
public bool condition;
}
我尝试了像这样的手动解组
static extern void fillTestArrayWithAlloc(ref IntPtr td, ref int size);
并像这样自动解组
static extern void fillTestArrayWithAlloc([Out] TestData[] td, ref int size);
但是在这两种情况下它都会执行内存复制,这是不受欢迎的。有没有办法在没有数据副本的情况下做到这一点?
祝你好运 彼得
答案 0 :(得分:1)
函数声明的第一个版本不应该导致所有数据被复制:只有指针和长度值被编组。
我认为你应该能够实现一个迭代器或枚举器,它使用TestData
直接从IntPtr
指向的非托管内存中一次封送一个Marshal.PtrToStructure
结构。在迭代时,您需要执行一些unsafe
指针算法以从一个实例移动到另一个实例。
这种方法应避免批量复制整个结构。祝好运。