How to convert from byte ptr to type instance ?
BlitzMax Forums/BlitzMax Programming/How to convert from byte ptr to type instance ?
| ||
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. |
| ||
Probably like convert = Byte Ptr(m) ? |
| ||
Instead of m = convert you could trytmp: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. |
| ||
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. |
| ||
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 :) |
| ||
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. |
| ||
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. |
| ||
Object variables are really 'pointers' anyway Perhaps he doesn't want type-safe pointers? |
| ||
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 ? |
| ||
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! |
| ||
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? |
| ||
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. |
| ||
Ok I'll use your suggestion of handle then, thanks. |
| ||
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> |
| ||
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 |
| ||
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 |