将数据从 C++ 传递到 C# 的最有效方法
Most efficient way to pass data from C++ to C#
我正在寻找将大量数据从C++(结构或值类?)传输到C#类的最佳方法,尽可能少地复制数据。 在下面的示例代码中,我有一个 SubClass 对象的向量,它有可能非常大(10+ 百万)。 所以我想尽可能避免数据复制。
我应该/我可以先在 GC 中分配对象并直接在 c++ 中使用它们而忘记本机 c++ 结构吗? (性能是我关心的。
或者,是否有一些技巧可以利用C++中分配的内容而不会导致数据复制?
下面是一些示例,类似于我想用作托管代码和非托管代码之间的传输的内容。
#include <string>
#include <vector>
struct SubClass {
std::string DataItem1;
// lots more here
std::string DataItem50;
};
struct Sample {
int IntValue;
std::string StringValue;
std::vector<std::string> SmallList;
std::vector<SubClass> HugeList;
};
如果我能避免使用 pinvoke 和 COM 类进入杂草,我更喜欢它。
按照 Unity 的示例(使用 C#),本机插件示例使用 GC 句柄将数据从 C# 传输到C++。我们可以尝试相反的方法,从 C# 将数据发送到 C++。
固定 C# 变量以加快复制速度。
using System;
using System.Collections;
using System.Runtime.InteropServices;
// vertices is a Vector3[], where Vector3 is a struct
// of 3 floats using a sequential layout attribute
void test(){
GCHandle gcVertices = GCHandle.Alloc (vertices, GCHandleType.Pinned);
}
使用封送处理将句柄传输到C++。你必须复制一些东西是不可避免的。在这里复制指针应该足够好。根据文档Microsoft有关封送处理的更多信息。
[DllImport("your dll")]
private static extern void SendHandle(IntPtr vertexHandle, int vertexCount);
SendHandle(gcVertices, vertices.Length);
在 C++ 中,你将收到句柄作为指向所选C++类型的指针类型。在本例中,vertices
是 3 个浮点数的结构列表。参考代码决定使用 float *
.您只需要根据指向的类型正确进行指针算术,包括void *
的情况。
extern "C" __decl(dllexport) void SendHandle(float* vertices, int vertexCount);
此处的示例代码直接从指针复制数据,但您也可以写入指针的位置。
for (int i = 0 ; i < vertexCount; i++)
{
// read from C# heap
float x = vertices[0];
float y = vertices[1];
float z = vertices[2];
// write to C# heap
*vertices = sqrt(x);
*(vertices + 1) = sqrt(y);
*(vertices + 2) = sqrt(z);
vertices += 3; // because it is a list of struct of 3 floats
}
从 C# 端清理固定句柄以恢复垃圾回收器。
gcVertices.Free();
至于字符串,我相信互操作库有一个为您处理指针算术和复制的实现。您可能可以直接在公开的导出函数中使用字符串类型,只要您指定如何使用 C# 中的 MarshalAs
属性和 C++ 中的库封送它(如果您不转换为 C 类型 char *
)。
- 在C++中初始化向量映射的最有效方法
- 将此布尔值传递给此函数的最有效方法是什么?
- 比较C++变量的最有效方法
- 在 c++ 中解决段树以外的范围查询的有效方法是什么?
- 存储变量的更有效方法是什么?
- 确保套装新鲜度的有效方法
- 当映射包含字符串向量作为值时,从值中获取键的有效方法
- 映射唯一值和重复值的有效方法.可以访问键或值的位置
- 在C++事务之间存储大量字符数据的有效方法
- 在unordered_multimap中精确迭代一次每个键的有效方法
- 一种将 Dart 中的字节数据转换为 C++ 中的无符号字符*的有效方法?
- 检查两个向量是否并行的最有效方法
- 从浮点数中删除小数部分但保留类型的有效方法
- 传递非泛型函数的最有效方法是什么?
- 按升序打印矢量的所有元素直到它为空而没有重复项的最有效方法是什么?
- 创建字符串数组的有效方法
- 返回一个引用C++中另一个类对象的对象的有效方法
- C++去除前x个元素的有效方法,在不改变向量大小的情况下将第x+1个元素推到第一个
- 将一种数据类型的向量复制到同一数据类型的结构向量中的有效方法是什么
- 从std::map值中获取密钥的有效方法