How to convert from byte ptr to type instance ?

BlitzMax Forums/BlitzMax Programming/How to convert from byte ptr to type instance ?

skn3(Posted 2005) [#1]
Is it even possible ? or is it part of the whole issue to ctype/carray mentioned in another thread.

Type mytype
End Type

Local m:mytype,convert:Byte Ptr

m = New mytype
convert = m
m = convert


This doesn't work.


ImaginaryHuman(Posted 2005) [#2]
Probably like convert = Byte Ptr(m) ?


teamonkey(Posted 2005) [#3]
Instead of m = convert you could try
tmp:mytype ptr = mytype ptr(convert)
convert = tmp[0]

?

That is, convert the Byte Ptr to a MyType Ptr first, then dereference it to get a MyType. Might not work though.


skn3(Posted 2005) [#4]
Doesn't work annoyingly. In the meantime, and again quite annoyingly I have had to revert to using an array of type pointers and an index to reference. Sort of defeats the point of having pointers in the first place.


Dreamora(Posted 2005) [#5]
there is a simple workaround if you know the size of the original object:

Type mytype
	Field val:Int
End Type

Local m:mytype,k:mytype
Local convert:Byte Ptr
Local size:Int

m = New mytype
m.val = 10
convert = m
size = SizeOf(m)

MemCopy (Byte Ptr(k),convert,size)


Print k.val

Delay 2000


PS: I use this to copy type instances :)


skn3(Posted 2005) [#6]
It's not really a work around because it requires a potentialy hefty mem copy operation. The idea of having a pointer is that you reference an existing "object" rather than recreating it.


marksibly(Posted 2005) [#7]
Hi,

No, there is no easy way to do this.

What do you want it for? Object variables are really 'pointers' anyway, so it doesn't gain you anything performance wise.


FlameDuck(Posted 2005) [#8]
Object variables are really 'pointers' anyway
Perhaps he doesn't want type-safe pointers?


skn3(Posted 2005) [#9]
Well it is related to winapi. Envolving the window/bmax type indexing problem. You can easily assign a pointer to a speciffic window using a custom windows class that has extra window bytes. Then you have instant access to a bmax type per window, isntead of having to search a list of hwnds to find a match each and every msg loop.

Im sure there are many other reasons to be able to do this, but the one above is a good enough example of what its good for really.

The way it works is like this.

Create window in winapi
Create gadget instance in bmax
Store pointer to gadget instance in the USERDATA belonging to that window
When message is recieved with hwnd, use GetWindowLong to check if the window has an associated gadget instance in bmax.

* voila very effecient windows messaging.

I have reverted to using an array of type instance, and store the array index with the window. Its usable but could be a whole lot easier if we could just cast from pointer to type. As it is, it means I have to mess with resizing arrays, and lose all the functionality of using a linked list.

Oh and this is what I have to end up doing to get around the fact you cant cast from pointer to type.
If msg = api_WM_NCCREATE
	'declare locals
	Local bank:TBank,pointer:Byte Ptr
	bank = CreateStaticBank(lparam,4)
	pointer = Byte Ptr(bank.PeekInt(0))
	bank = CreateStaticBank(pointer,4)
	pointer = Byte Ptr(bank.PeekInt(0))
	bank = CreateStaticBank(pointer,4)
	'setup gadget
	gadget = acwin32_gadgetarray[bank.PeekInt(0)]
	gadget.hwnd = hwnd
	'set gadget arrayid in window extended bytes

	api_SetWindowLong(hwnd,acwin32_windowbytes_arrayid,gadget.arrayid)

End if


Not very pleasant aye ?


marksibly(Posted 2005) [#10]
Hi,

I'd recommend using object handles instead.

At the moment, these aren't toooo elegant to use but their advantage is that you wont accidentally 'leak' objects - eg: if you convert an object to a byte ptr and there are NO references left to the object it may get accidentally 'flushed', resulting in really hard to find bugs.

You can perform object/handle conversions using functions, but it's a bit messy. For a kludge around until I clean this up...

Extern
Function bbHandleToObject:Object( handle )
Function bbHandleFromObject:Int( obj:Object )
End Extern

Type TMyType
   Field x=1
End Type

Local obj:TMyType=New TMyType

Local handle=bbHandleFromObject( obj )

obj=TMyType( bbHandleToObject( handle ) )

Print obj.x

Release handle 'done with object!



skn3(Posted 2005) [#11]
But doesn't handle go through a list to search for the object associated to the handle ?

You would lose the bennifit of using a direct reference to the object.. Or am I missing something?


marksibly(Posted 2005) [#12]
It goes through a hashtable - faster than a list lookup, slower than a plain pointer.

Unless you've got 1000 odd windows, the speed difference is likely to be negligible though.


skn3(Posted 2005) [#13]
Ok I'll use your suggestion of handle then, thanks.


FlameDuck(Posted 2005) [#14]
It goes through a hashtable - faster than a list lookup, slower than a plain pointer.
Marginally faster. HashTables and pointers both have constant time complexity for random access, lists have linear. So the speed difference between using a hashtable vs using a pointer is likely to be negligable.

Incidently, could we get a THashTable type, if hashtable code is already present? Please? :o>


CoderLaureate(Posted 2005) [#15]

Type mytype
	Field val:Int
End Type

Local m:mytype,k:mytype
Local convert:Byte Ptr
Local size:Int

m = New mytype
m.val = 10
convert = m
size = SizeOf(m)

MemCopy (Byte Ptr(k),convert,size)


Print k.val

Delay 2000



PS: I use this to copy type instances :)



@Dreamora: This is bloody brilliant! Using this technique. Someone should be able to impliment a form of "Serialization".

You could "Serialize" an instance of an object into a TStream. The TStream could transfer the object (via internet, or file) to another computer.

Of couse, the destination computer would have to have the same Class/Type definition set up. But the "Serialized" data could then be "De-Serialized" to reform the same object with it's different methods/data on the new machine.

This has many possibilities.

-Jim


DStastny(Posted 2005) [#16]
Here is method I used to store BMAX Objects in external Pointers.

Note use of Global TList to manage external references.

First is "C" file that defines magic functions :)

objecttoptr.c

/* Simple Functions to translate Object to Pointer and Back */
/* Note Use of char* as pointers                             */
char* ObjectToBytePtr(char* AObject) { return AObject;}
char* BytePtrToObject(char* AObject) { return AObject;}


Now BMAX file that demonstrates Use

objecttoptr.bmx

Import "objToptr.c"
' Note the change to extern declaration..  linker only matches name
' so here we can fiddle with BMAX parameters to pass object the "C" code sees it as a 
' Char* which is Byte Ptr to BMAX
Extern "C"
	 Function ObjectToBytePtr:Byte Ptr(AObject:Object)
	 Function BytePtrToObject:Object(ABytePtr: Byte Ptr)
End Extern

' Important we make global list of all objects we assign external reference for
' Also important to remove object from the list when no longer externally assigned or they won’t be deleted by BMAX
' Every time you cast Object to Byte Ptr add to External List
' This will maintain BMAX reference counting

Global ExternalObjects : TList= New TList

Type TMytype
	Field Text:String
	Method New()
		Print "Created TMytpe:"+toString()
	End Method
	Method Delete()
		Print "Destroyed TMytpe:"+toString()	
	End Method
End Type

Local bptr : Byte Ptr
Local mt:TMyType= New TMyType;
mt.Text="Stored in Byte Ptr"
' Convert the Object to Byte Ptr
bptr=ObjectToBytePtr(mt)
' Add it to our ExtrenalObjects List to manage Reference Count
ExternalObjects.AddLast(mt)
' Clear our local Type variable
mt=Null
' Call FlushMem and notice Object not Deleted
FlushMem
' Convert the Byte Ptr back to object
mt= TMyType(BytePtrToObject(bptr))
Print mt.Text
' set our external reference to null
bptr=null
' requires we remove reference to mt from list
ExternalObjects.Remove(mt)
' Clear our local variable 
mt=null
' Notice after flushmem object is deleted by BMAX
FlushMem
Input("Hit Enter to quit")


As Mark pointed out this can be very dangerous however for managing BMAX objects in External memory if you understand that concept then these functions and this technique will do it very effectively

Hope this helps

Doug Stastny