genonymous
genonymous

Reputation: 1750

How to typecast data pointed by void pointer to a fixed size int array in C#?

This is a similar to the following SO question:

cast-void-pointer-to-integer-array

c-pointers-pointing-to-an-array-of-fixed-size

However, the difference is that I want to achieve this in C# using 'unsafe' feature through which we can use pointers.

e.g.

Following code works in C:

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

where 'ptr' is void pointer. How can be this achieved in C#?

Upvotes: 2

Views: 4289

Answers (2)

xxbbcc
xxbbcc

Reputation: 17327

I'm not entirely sure that this is what you're looking for, but one example would be like this:

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;
    }
}

When taking the address of an array, you have to take the address of the first item in the array - hence &items[0] in the example above.

If you receive the pointer as a void* function parameter, you have to cast it inside the function:

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;
}

If you receive a void* from an external source, you'll have to somehow know how many bytes (or ints, etc.) are safe to access through the pointer. The data may be delimited by a special value (like a terminating 0 or something else) or you'd need a count or bytes / elements to safely access memory through the pointer.

Update

Here's an example of calling an unmanaged function implemented in 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 has more examples on various pointer operations. Also, here's another article about marshaling arrays.

Upvotes: 0

Simon Whitehead
Simon Whitehead

Reputation: 65079

You can simply cast it to an int* pointer.. hoping for the best.. obviously:

// 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

That said.. you will have to be vary careful with bounds checking. AFAIK there is no direct translation that allows for bounds.

Upvotes: 0

Related Questions