Wrapping this Method for BMax

BlitzMax Forums/BlitzMax Programming/Wrapping this Method for BMax

Gabriel(Posted 2006) [#1]
Ok, Here's a Method I have wrapped for BlitzMax, which I believe I have wrapped incorrectly.

c++
extern "C" __cdecl cTV_3DVECTOR CTVPhysics_GetBodyPosition(CTVPhysics* Ha,int rigidBodyIndex) {
	return Ha->GetBodyPosition(rigidBodyIndex);
}


bmx
Function CTVPhysics_GetBodyPosition:Byte Ptr(Ha:Byte Ptr,rigidBodyIndex:Int)


I'm getting an unhandled memory exception on it though. I know that Ha->GetBodyPosition returns a cTV_3DVECTOR, that's correct. But normally when I get objects back from my C++ wrapped functions, get them back as Blah* not just Blah. Could this be the problem? If so, what can I do? I can't just change the return type of the C++ function to cTV_3DVECTOR* because it complains that the function return type does not match ( because, as I said, Ha->GetBodyPosition returns a cTV_3DVECTOR, not a cTV_3DVECTOR*


N(Posted 2006) [#2]
Try this:

extern "C" __cdecl void CTVPhysics_GetBodyPosition(CTVPhysics* Ha,int rigidBodyIndex, float* vector) {
     cTV_3DVECTOR vec = Ha->GetBodyPosition(rigidBodyIndex);
     memcpy(vector,&vec,sizeof(cTV_3DVECTOR)); // copy the data to the output vector ('vector')
}



Function CTVPhysics_GetBodyPosition(Ha:Byte Ptr,rigidBodyIndex:Int, output:Float Ptr)



Dreamora(Posted 2006) [#3]
Why not simply change the return then as well to *.... when you set cTV_3DVECTOR* as return type? :-)


N(Posted 2006) [#4]
Because the vector is not allocated in the heap, it's in the stack. So you're returning a pointer to something that, once out of the stack frame, is freed. You can probably guess what's wrong with that.


Gabriel(Posted 2006) [#5]
Thanks for the suggestion, Noel, but I get the same result. Still an unhandled memory exception.

How does this look :

extern "C" __cdecl cTV_3DVECTOR* CTVPhysics_GetBodyPositionTwo(CTVPhysics* Ha,int rigidBodyIndex) {
	cTV_3DVECTOR v=Ha->GetBodyPosition(rigidBodyIndex);
	return new cTV_3DVECTOR(v.x,v.y,v.z);
}




N(Posted 2006) [#6]
That could work, however you'd better have a way to delete the vector.


Sweenie(Posted 2006) [#7]
I would go for the method Noel suggested.
Ogre returns the whole vector as well and that is how I solved it.


Gabriel(Posted 2006) [#8]
Is there a flaw inherent in my way of doing it then? Because unfortunately Noel's method also gave me an unhandled memory exception.


gman(Posted 2006) [#9]
i used your proposed second method extensively in the Irrlicht mod. just have a delete routine and remember to incorporate that in your BMAX wrapper when you are done with it and your good to go. the only thing wrong with the creating a new based on the return value is making sure you clean it up properly.


Sweenie(Posted 2006) [#10]
Is there a flaw inherent in my way of doing it then? Because unfortunately Noel's method also gave me an unhandled memory exception.

Well, is the float ptr passed by the bmax app valid?
I assume the 3DVector contains three floats, so it should be something like this...
Local Position:Float[3]
MyWrappedGetPositionFunction(varptr Position[0])


Gabriel(Posted 2006) [#11]
Thanks for the confirmation, GMan. If you used it for Irrlicht, that's good enough for me. I do already have a delete method in place which deletes the wrapped object pointer, as I have no way of knowing how it was created.

Sweenie: Yes, that's how I had it and it was erroring. Perhaps I had something wrong somewhere, but some of these returned objects are going to be far more complex, made out of mixed datatypes and possibly even other objects, so doing things this way would mean having to pass back into a bank or block of memory and pull it all apart at the other end, so I think just creating a new one in the wrapper is easier there anyway.