P-Invoke 解组在 DLL 中分配的结构数组
我需要将大量(理论上最多几 TB,仅受可用内存限制)数据从基于 C/C++ 的核心 DLL(用于管理、过滤和分配数据)铲到 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);
但是在这两种情况下它都会执行内存复制,这是不希望的。有没有办法在不复制数据的情况下做到这一点?
此致 彼得
I have a requirement to shovel large amounts (theoretically up to a few terabytes, only limited by available memory) of data from a C/C++ based core DLL which manages, filters and allocates the data, to a C# GUI (which only reads the data). It would be optimal if the data are never duplicated but only accessed per reference from the C#. The signature of my DLL's method is currently the following (I can make changes there):
extern "C" {
typedef struct {
wchar_t* name;
__int32 t;
float v;
bool condition;
} TestData;
__declspec(dllexport) void fillTestArrayWithAlloc(TestData** td, __int32* size);
};
The array length is not known to C# and can be anything between 1 and millions....
I mapped the structure like this:
[StructLayout(LayoutKind.Sequential)]
struct TestData
{
[MarshalAs(UnmanagedType.LPWStr)]
public String name;
public Int32 t;
[MarshalAs(UnmanagedType.R4)]
public float v;
public bool condition;
}
I tried both manual unmarshalling like this
static extern void fillTestArrayWithAlloc(ref IntPtr td, ref int size);
and automatic unmarshalling like this
static extern void fillTestArrayWithAlloc([Out] TestData[] td, ref int size);
But in both cases it performs a memory copy, which is undesired. Is there a way to do it without a data copy?
Best regards
Petr
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
函数声明的第一个版本不应导致复制所有数据:仅对指针和长度值进行编组。
我认为您应该能够使用
实现一个迭代器或枚举器,一次直接从
。您将需要执行一些IntPtr
指向的非托管内存中编组一个TestData
结构。 Marshal.PtrToStructure不安全
指针算术,以便在迭代时从一个实例移动到另一个实例。这种方法应该避免大规模复制整个结构。祝你好运。
The first version of your function declaration should not cause all the data to be copied: only the pointer and length value will be marshalled.
I think you should then be able to implement an iterator or enumerator which marshals one
TestData
structure at a time directly from the unmanaged memory pointed to by theIntPtr
, usingMarshal.PtrToStructure
. You will need to do someunsafe
pointer arithmetic to move from one instance to another as you iterate.This approach should avoid wholesale copying of the entire structure. Good luck.