2

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#?

3
  • How do you get the pointer in C#? You can either start with an int* or you have to receive it as such. If you receive a void*, you'll have to cast it to be able to use it. Commented Sep 12, 2014 at 1:34
  • Could you explain why exactly do you want to do that? Also, I belive the C# type system doesn't have fixed sized arrays. Commented Sep 12, 2014 at 2:01
  • @xxbbcc and : I understand that I can cast a void pointer to int pointer, however, I want that to be casted to a fixed length array. This sometimes becomes necessary when there is some standard third party library function which takes fixed length array as an input. e.g. void standardFunction(int []). I cannot pass just an integer pointer to this function. Commented Sep 12, 2014 at 22:51

2 Answers 2

0

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for answering. But I know above logic, what I want is direct translation which will allow for bounds. I know how to do it in C and that is also mentioned in the the two SO questions which I have embedded in the question. I am looking a C# way to do it.
0

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.

4 Comments

Thanks for answering. I know I can access memory pointed by void pointer by casting it to say int pointer and then increment the pointer and then again access the next location and so on. However, if I have to pass this data to some other standard third party function which accepts fixed size array, I can not control the above logic in that third party standard function because I cannot edit it and I am not supposed to edit it.
@genonymous It depends on what exactly the 3rd party function expects. If it expects an int* to an array of 5 items then in C# you can create an array of 5 int-s, get the address of the first element and then pass that pointer to the 3rd party call. Arrays are continuous so knowing the address of the first element, the size of an element and the number of items in the array tells you everything about the array.
@genonymous I added a small example of calling an external function for you.
@genonymous I only now saw your other comment and realized I may have misunderstood what you asked. I added another article to the answer about declaring signatures to pass fixed size arrays to unmanaged functions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.