如何在C#中将void指针指向的数据类型转换为固定大小的int数组

本文关键字:类型转换 数组 int 数据 中将 void 指针 | 更新日期: 2023-09-27 18:21:39

这类似于下面的SO问题:

将void指针强制转换为整数数组

固定尺寸的c点对点阵列

然而,不同的是,我希望在C#中使用"不安全"功能来实现这一点,通过该功能我们可以使用指针。

例如

以下代码在C:中工作

int (*arr)[10] = (int (*)[10]) ptr;

其中"ptr"是无效指针。如何在C#中实现这一点?

如何在C#中将void指针指向的数据类型转换为固定大小的int数组

您可以简单地将其强制转换为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提供了更多关于各种指针操作的示例。此外,这里还有另一篇关于封送处理数组的文章。