Skip to main content
gamedev.net
🔒 Locked

[.net] Pointer to Array

Started by Jonas B Apr 23, 2006 at 4:58 AM 25 replies 5.1k views
Original Post
Jonas B
Jonas B
I need to speed up some memory copying by using Buffer.BlockCopy(), but I can't find a way to cast my *byte to the required byte[]. Any tips?
orbano
orbano
i dont understand the problem. could you explain it?
"Knowledge is no more expensive than ignorance, and at least as satisfying." -Barrin
Jonas B
Jonas B
Buffer.BlockCopy() only accepts Arrays, and all I've got is a pointer. I thought Arrays and Pointers were similar enough to allow casting between them, but

byte* ptr = null;
byte[] array = (byte[])ptr;

doesn't compile.
thannett
thannett
You can try something like this:

byte test = 'a'; //Example bytebyte* ptr = &test //Pointer to Example bytebyte array[0]; //Array of bytesarray[0] = *ptr; //Makes array[0] equal to the contents of ptrcout << array[0] << endl; //Prints contents of array[0]
Jonas B
Jonas B
But that would mean copying the data byte by byte manually, which is what I'm trying to avoid...
bakery2k1
bakery2k1
Quote:

byte* ptr = null;
byte[] array = (byte[])ptr;


Are you sure a cast is required at all? Have youy tried passing "ptr" directly?
orbano
orbano
if you have a byte[] varname, the expression 'varname' is a pointer to the first element of the array (if its allocated), so its type is byte*.
"Knowledge is no more expensive than ignorance, and at least as satisfying." -Barrin
Jonas B
Jonas B
Sorry folks, I forgot to specify that the language is C#. The cast should work in C++ (and probably C++/CLI), so I (still) hope there's a way to do it in C# as well.
I'll try to remember that .NET != C# next time!

So, any clues for C#?
Machaira
Machaira
What do you have a pointer to? If you're using C# I thought it didn't have pointers?
Former Microsoft XNA and Xbox MVP | Check out my blog for random ramblings on game development
Jonas B
Jonas B
Pointers are allowed in "unsafe" blocks, in this case it's a pointer to a surface's GraphicsStream.InternalData.
Bob Janova
Bob Janova
Can you use Marshal.Copy() instead? A pointer isn't equivalent to an array under .Net, because arrays know how long they are, so you won't be able to do a simple cast and I can't see a method on the Array class that would allow you to create one.
Jonas B
Jonas B
Marshal.Copy() *almost* works - but this is from one unmanaged pointer to another, and all Marshal.Copy() methods involve Arrays in some form.

I can get by without it, it just annoys me to not have access to (possibly) optimized copy funtions...
orbano
orbano
then simply iterate through your array given by the pointer (you must know its length), and put it into an array:

byte* bptr = your pointer thingie;
int l = length of the array pointed by your byte* ptr;
byte[] myArray = new byte[l];
for(int i=0; i{
myArray = *bptr; //i dont know how to reference in c#
++bptr;
}

one more thing: if you cant tell the length of the array (l), then no God will tell you that :)
"Knowledge is no more expensive than ignorance, and at least as satisfying." -Barrin
Jonas B
Jonas B
Thanks, but that's the manual entry-by-entry solution I already have and am trying to avoid. No optimizations there.
orbano
orbano
you are moving data between a safe and an unsafe variable. thants the thing that .net doesnt really like and will not support with specific functions i think
"Knowledge is no more expensive than ignorance, and at least as satisfying." -Barrin
Jonas B
Jonas B
Sorry, my bad - your example was not like what I have. I have two unsafe pointers. Marshal.Copy() handles Pointer to Array copies, so that's allowed.
Enselic
Enselic
Are you sure you need to optimize that routine in the first place? Even though things look dirty, it doesn't mean it executes dirtly [smile].

And I'm curious of your more high level problem so to speak. What are you trying to do in a broad sense?

I am asking because I suspect you are a C/C++ guy just starting with C#, wanting to do things the C/C++ way when the prefered would be the C# way.
Jonas B
Jonas B
Actually, C++ was a long time ago...
One of the uses is copying data from a sound buffer to a D3D surface (for effects processing on the GPU). At least in C++ I seem to remember that memcpy() can be significantly faster than the manual approach.
capn_midnight
capn_midnight
Quote:
Original post by Enselic
Are you sure you need to optimize that routine in the first place? Even though things look dirty, it doesn't mean it executes dirtly [smile].

And I'm curious of your more high level problem so to speak. What are you trying to do in a broad sense?

I am asking because I suspect you are a C/C++ guy just starting with C#, wanting to do things the C/C++ way when the prefered would be the C# way.


I have to agree with Enselic. Just because there are pointers in C# doesn't mean you should use them.

Actually, C# implements object references similarly to Java. What is called an "object reference" is actually a pointer to that object, in C++ terminology. These would be equivalent blocks of code in both languages:
//C#void doSomething(MyClass a){   a.modify(); //calling method of doSomething will see changes to a   a = new MyClass(); //wasted effort, the object reference is only a copy}//C++void doSomething(MyClass* a){   a->modify(); //calling method of doSomething will see changes to a   a = new MyClass(); //wasted effort, the object pointer is only a copy}

The significance is the parameter copying semantics. If the C# method were copied verbatim as a C++ function, then calling the function will create copies of the objects that are passed to the function. In C#, copies of the object references are made. When the C++ version in the code above is called, the object pointers are copied before being passed to the function. In both cases, the underlying object is NOT copied.

If we want equivalant C# code to C++ pass-by-reference, then we use the same ampersand syntax
//C++ and C#void somethingElse(MyClass& a){    //blah!}


There is no equivalent C# code for C++ pass-by-value for objects. Pass-by-value is used for stack-types (primitives, enums, structs), but never for heap-types.

The difference between pointers and references in C# is that the former is unmanaged and the latter is managed. The *only* time you need pointers in C# is when you are interoping with unmanaged C++ assemblies that require pointer parameters. There is a reason why you need a "unsafe" code block as well as a compiler flag to use pointers in C# -- you're not supposed to use them for general purpose work, they are only for very special purposes.
Jonas B
Jonas B
I'm already a strong believer of the Way of the Managed Languages, but thanks anyway!
Pointers are very useful when processing certain types of data. Have you tried C# Image manipulation using Get/SetPixel()? Dog slow, the only decent way is to lock it and go unsafe with the pointer.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.