brainpop- Cast to and from a pointer

BlitzMax Forums/BlitzMax Programming/brainpop- Cast to and from a pointer

Damien Sturdy(Posted 2008) [#1]
Hi All,

Bit of a brainfart here. some C++ side code we are using requires we pass it a Byte PTR, and at a later point it returns this same Byte PTR.

THing is, in blitzmax it is an Object. It is cast to a pointer, sent, then retrieved later.

How can I cast the returned Byte PTR back to an object?


ziggy(Posted 2008) [#2]
Not sure how to do it properly, but keep in mind to store a pointer to the object instance alive on BlitzMax code, if you don't want your object to be deleted by the GC while it is being processed by the C++ code.


grable(Posted 2008) [#3]
You could try something like this:
Local obj:Object = New TList
Local res:Object
Local p:Int Ptr = Int Ptr Varptr res
p[0] = Int yourfunc( obj)
Print "res  : " + (Int Byte Ptr res)
Print "obj  : " + (Int Byte Ptr obj)
Print "equal: "+(res = obj)

Function yourfunc:Byte Ptr( p:Byte Ptr)
	Return p - 8 ' this is important, object -> ptr skips 8 bytes apparantly
EndFunction

But it might mess with the ref count or cause some other GC releated issue.


Brucey(Posted 2008) [#4]
p - 8 ??

If you are using C++, why not just let C++ worry about it? No point jumping through hoops you don't have to.

' some BlitzMax code
Extern
    Function GoodbyeObject(obj:Object)
    Function HelloObject:Object()
End Extern

// some C++ glue...
extern "C" {

  void GoodbyeObject(void * obj);
  void * HelloObject();

}


As ziggy points out, you'll need to keep the object reference alive somehow (either in BlitzMax or with C++).


Dreamora(Posted 2008) [#5]
you can not cast byte ptr to an object anymore. so if you return byte ptr it will remain a memory block


Damien Sturdy(Posted 2008) [#6]
Ok, the object is safe in blitzmax and is alive for as long as the callback is in use, so GC is not an issue.


you can not cast byte ptr to an object anymore. so if you return byte ptr it will remain a memory block



That puts one HELL of a bummer on something. Why the hell cant you cast the byte ptr to an object anymore!?

everyone else: Thanks. We cannot change the C++ side code. In fact what I am doing is storing a pointer to a Max object with a C++ object (a newton body in fact.) the newton callback (which is in blitzmax and working fine) is then supposed to retrieve this pointer and cast it back to an object, which contains forces etc that we want applied.

Ugh.


Brucey(Posted 2008) [#7]
Oh well... my example is the easiest to implement, and it known to work well - see many of my modules as examples.

Good luck with it :-)


Damien Sturdy(Posted 2008) [#8]
Yeah, its how I was doing it, but it didn't work, and the object that was returned was invalid. :-( Thanks though :-)

in fact, its how we're doing it with another type, but i guess there are some internal differences with the other type and this one (they use different functions C++ side too.)


Dreamora(Posted 2008) [#9]
[quote]That puts one HELL of a bummer on something. Why the hell cant you cast the byte ptr to an object anymore!?¨[/code]


because BM is type safe and typesafeness can not be ensured if you can cast "nothing" to a type.
but you can implement a method "fromBytePtr" and read out all the data into an existing type instance.


Damien Sturdy(Posted 2008) [#10]

but you can implement a method "fromBytePtr" and read out all the data into an existing type instance.



Ew. my lord. The reason is to keep Bmax Typesafe? seems like an anti-idiot technique to me. *sigh*

Sorry for being grumpy, I'm feeling a little let down by this to be honest.


Brucey(Posted 2008) [#11]
the object that was returned was invalid.

maybe you did something wrong?

If the library takes userdata as a void* then it won't be doing anything to it, only passing it back to you later.

So, passing it in as Object (no ptr conversion nonsense required), it will be returned as Object too - ie. same memory location. You just have to be absolutely sure you are holding onto the reference yourself.


Dreamora(Posted 2008) [#12]
Typesafeness is one of the most important OO concepts.
Even C++ has basics of that concept (not fully fledged as other languages, but at least it got better in the last few years)

Why do you think has the String class a fromCString and fromWString function?

Typesafeness is one of the most important mechanisms to create correctly working modules that idiots from outside can not break by stupidly casting incompatible stuff around.

It is important that it is like that, otherwise you could by accedint get some byte ptr data in that is incorrect and that would just crash the GC. That would be stupid!

If you don't want to do that, use extern types and generate the objects within C++ and only use them within BM.
Thats the simple alternative if you need shared objects.
That as well will take care that you don't get any GC conflicts


Damien Sturdy(Posted 2008) [#13]
I honestly think Bruceys solution, IE the solution we were already attempting to use, should work. Saying that, I believe that if a user wants to cast from a pointer to an object, then they should be able to.


If you don't want to do that, use extern types and generate the objects within C++ and only use them within BM.
Thats the simple alternative if you need shared objects.



It can't work like that, being an Ogre wrapper for blitzmax hehe. As I say though, I think something else might be up. Appologies for being a grump, and thanks for yourhelp guys.


Dreamora(Posted 2008) [#14]
Pointing a memory block to object can not work for a simple reason: it would not work with the GC driven background.
No managed language allows you to do that, you always have to write "wrapper code" that takes the byte data and returns you the object.
The common way is the "fromXY" function that returns the object. Lazy people have a method that overwrites the content of an already existing object with the data from the byte block. Reason is that it allows you to use a single object as temporary container for multiple data, if you are enumerating / iterating for example.


Brucey(Posted 2008) [#15]
Lazy people have a method that overwrites the content of an already existing object with the data from the byte block.

Well, no-one in their right mind would do that - although it happens to be done in the BRL FreeTypeFont module, from what I remember :-)


Dreamora(Posted 2008) [#16]
Well as mentioned, its for lazy people.
I only use it on classes where I know that I only need them temporally inbetween and where I don't want to flood the GC (vectors banks for example), so the performance raises drastically.