convert managed array to unmanaged array, (c++/c#)

Started by
3 comments, last by Riviera Kid 17 years, 11 months ago
Hi, I am trying to write a c# wrapper for my engine. I have had some success. I have come across an issue which i am struggling to resolve. I have an array of vertices, position/color/texcoord i am passing the array to my managed c++ wrapper. I want to convert the array to an unmanaged array so native c++ can use it. For individual variables i have been using the 'GCHandle' class which freezes the managed variable and passes back an IntPtr where i can get a void* for my native c++. However this class doesnt have anything to do with arrays. I have been looking at the 'Marshal' class which has some information on it but its horrid and the documentation is crap. Can anyone help? here is my barebone managed c++ function.

UINT CreateVertexBuffer(UINT size,
                        UINT type,
                        UINT nVerts,
                        array<Object^> ^ verts ,
                        bool bDynamic)
{	
	UINT nVBID;			
	pPrimMan->CreateVertexBuffer(&nVBID,size,type,nVerts,***VERTS***,bDynamic);		
	return nVBID;
}




Thanks
--------------------------------Dr Cox: "People are ***tard coated ***tards with ***tard filling."
Advertisement
Its looks like you're using C++/CLI not managed C++ (it's inferior predecessor), what you want to do is use pin_ptr, here is an example of what you are trying to do.

Lastly are you really sure you need to use an array of handles of type object, you know you can use both generics & templates in C++/CLI.
thanks for the help however i am still having some trouble.
i have tried the below but all the values are screwed up when my data reaches native c++.
i have found lots of stuff on arrays of type 'int' but nothing for 'Object'.
Does anybody know exactly how to this?
i have wasted over a day trying to figure it out.
give me an answer.

UINT CreateVertexBuffer(UINT size,                        UINT type,                        UINT nVerts,                        array<Object^> ^ verts ,                        bool bDynamic){        Object^ o = verts[0];				        pin_ptr<Object^> pVerts = &o;        UINT nVBID;				HRESULT hr = pPrimMan->CreateVertexBuffer(&nVBID,size,type,nVerts,pVerts,bDynamic);					return nVBID;}
--------------------------------Dr Cox: "People are ***tard coated ***tards with ***tard filling."
Don't demand for answers you have to be patient, C++/CLI is relatively new not many people know much about it so you're going to get very little response.

First it appears you're not doing it correctly, when have a pin_ptr then you can assign it to a raw pointer to be passed off to unmanaged APIs, the GC collector will not move the refered object in memory until the end of scope in which pin_ptr was defined in.

I need more details before i can give more help, what are the types of argumenets that pPrimMan->CreateVertexBuffer takes?, what does this method do exactly do, etc, etc.

If this array is meant to be an array of vertices or texcoords, etc, ete then generally you be dealing with (or should be) CLI value types therefore you really want an array of CLI value types.

You don't want an array of handles to object becuase that will cause boxing of value types, when you have an array of reference types you don't have an array that holds it's elements in memory contiguously anymore like you would have if you used value types. If you have an array of boxed value types then you'll have to deal with each individual elements, unboxing them, doing something, then loop again instead of working with the entire array in one go.

This is why i'm telling you, you'd better off using generic function for your interface from other .NET languages to C++/CLI. You should have something that looks like this:

generic < typename Vertex > where Vertex : value classint CreateVertexBuffer(array<Vertex>^ verts, bool bDynamic) {     pin_ptr<Vertex> p = &vertes[0];     void* pp = p;     int nVBID = 0;     pPrimMan->CreateVertexBuffer(          &nVBID,          sizeof(Vertex),          MapCLITypeToMineTypeId(Vertex::typeid)          verts.Length,          pp,          bDynamic);		     return nVBID;}


I'm not sure if that is the intended behaviour you're looking for without more information, take note of the generic constraint.

[Edited by - snk_kid on May 20, 2006 6:44:14 AM]
i want to take an array of objects in c# and pass them to native c++ as void*.

i tried to use value types but when i tried to create an array in c# i couldnt access any of the public properties (i could in c++).

i defined the struct in mc++

[Edited by - Riviera Kid on May 20, 2006 1:25:04 PM]
--------------------------------Dr Cox: "People are ***tard coated ***tards with ***tard filling."

This topic is closed to new replies.

Advertisement