如何在C#中将void指针指向的数据类型转换为固定大小的int数组
本文关键字:类型转换 数组 int 数据 中将 void 指针 | 更新日期: 2023-09-27 18:21:39
这类似于下面的SO问题:
将void指针强制转换为整数数组
固定尺寸的c点对点阵列
然而,不同的是,我希望在C#中使用"不安全"功能来实现这一点,通过该功能我们可以使用指针。
例如
以下代码在C:中工作
int (*arr)[10] = (int (*)[10]) ptr;
其中"ptr"是无效指针。如何在C#中实现这一点?
您可以简单地将其强制转换为int*
指针。。抱着最好的希望。。显然:
// unsafe {}
var a = stackalloc int[5];
a[0] = 1;
a[1] = 2;
a[2] = 3;
a[3] = 4;
a[4] = 5;
var v = (void*) a; // cast to void as example
for (var i = 0; i < 5; i++)
Console.WriteLine((*(int*)v)++); // back to int - 1, 2, 3, 4, 5
话虽如此。。在边界检查时,您必须非常小心。AFAIK没有允许边界的直接转换。
我不完全确定这是你想要的,但有一个例子是这样的:
int[] items = new int[10];
unsafe
{
fixed ( int* pInt = &items[0] )
{
// At this point you can pass the pointer to other functions
// or read/write memory using it.
*pInt = 5;
}
}
在获取数组的地址时,必须获取数组中第一个项的地址,因此在上例中为&items[0]
。
如果您将指针作为void*
函数参数接收,则必须将其投射到函数内部:
public static unsafe void F ( void* pMem )
{
int* pInt = (int*) pMem;
// Omitted checking the pointer here, etc. This is something
// you'd have to do in a real program.
*pInt = 1;
}
如果您从外部源接收到void*
,您必须知道通过指针可以安全访问多少字节(或int等)。数据可能由一个特殊值(如终止的0
或其他值)分隔,或者您需要一个计数或字节/元素来通过指针安全地访问内存。
更新
以下是调用在C:中实现的非托管函数的示例
// Function declaration in C
#define EXPORTFUNC __declspec(dllexport)
#define MYDLLAPI __declspec(nothrow) WINAPI
EXPORTFUNC int MYDLLAPI MyFunc1 ( byte* pData, int nDataByteCount );
// Import function in C#
[DllImport ( "My.dll" )]
private static extern int MyFunc1 ( byte* pData, int nDataByteCount );
// Call function with data (in unsafe class / method)
byte[] byData = GetData ( ... ); // returns byte array with data
fixed ( byte* pData = byData )
{
int nResult = MyFunc1 ( pData, byData.Length );
...
}
MSDN提供了更多关于各种指针操作的示例。此外,这里还有另一篇关于封送处理数组的文章。