如何使用指针直接从托管代码中的非托管代码中读取矢量数据

how to directly read a vector data from unmanaged in managed code using it's pointer

本文关键字:非托管代码 读取 数据 托管代码 指针 何使用      更新时间:2023-10-16

我有一个控制台 c++ 应用程序创建一个向量并为其分配数据:

vector<char> demo_vector_1 = {
0x54, 0x48, 0x49, 0x53, 0x20, 0x49, 0x53, 0x20, 0x44, 0x45, 0x4D, 0x4F,
0x20, 0x44, 0x41, 0x54, 0x41
};

不,我有一个带有导出函数的托管 dll:

[DllExport]
static public void ReadThisVector(IntPtr v_ptr,long datasize)
{
//// Data processing ...
}

然后我在 c++ 中调用这个函数并将矢量数据指针传递给我的 C# 代码:

ReadThisVector((long)&demo_vector_1[0], demo_vector_1.size());

我在 c++ 和 c# 中打印出了矢量指针,它们匹配。

现在,我需要直接从 C# 代码访问并准备该向量的某些部分。 我尝试使用读取进程内存,但出现访问冲突错误。

如何将矢量数据直接读取到缓冲区字节数组甚至更好的 C# 列表? 我不想复制任何东西,只是直接访问,因为我的数据量会很大。

C#DLL加载在控制台和非托管进程的相同进程中,所以它应该访问它的内存但是如何呢?

我是否以正确的方式传递矢量指针?

注意:我不想使用内存映射文件。

我不确定你的数据类型是否正确。您现在拥有的代码适用于 64 位版本,但在 32 位版本中失败。这里有一种方法可以解决:

[DllExport]
static public void ReadThisVector( IntPtr v_ptr, uint datasize )
// C++
ReadThisVector( demo_vector_1.data(), (uint32_t)demo_vector_1.size() );

现在,关于你的问题 - 你可以打电话给Marshal.ReadByte。

或者,如果你有新式 .NET,并且可以使用不安全的代码,则可以从 2 个值创建ReadOnlySpan<byte>。如果您需要用于 IO 的数据,现代 .NET 具有类似Stream.Write(ReadOnlySpan<byte>)的东西,即流可以直接从非托管缓冲区写入而无需创建副本。

遗憾的是,无法将非托管内存直接强制转换为 C# 数组或列表。您要么需要复制,要么将 API 从数组/列表更改为跨度/指针。