Small addition to BRL Reflection: Get Function ptr
BlitzMax Forums/BlitzMax Module Tweaks/Small addition to BRL Reflection: Get Function ptr
| ||
Could be easily build into the Module, but this way the module does not need to be modified: A Small example how to use it: I needed this to automaticaly export Types as a Python-Module, maybe someone might find this usefull, too. |
| ||
Can it be used to get method pointers? |
| ||
Method pointers are not possible as Methods allways need an Object to be called. Internaly BRL.Reflection gets a method pointer whenever it invokes a method internaly, but puts the Self-Object on the stack before it calls the method. See TMethod.Invoke and the private _Call function in BRL.Reflection if you want to know more about it. |
| ||
It would be cool if the reflection module would support full function and type function support. |
| ||
Nice addition :) Can it be used to get method pointers? Not true method pointers, but it works. (code ripped shamelessly from BRL.Reflection) Function GetMethodFuncPtr:Byte Ptr( this:Object, name:String) If this And name Then Local typ:TTypeId = TTypeId.ForObject(this) Local meth:TMethod = typ.FindMethod(name) If meth Then If meth._index < 65536 Then Return bbRefMethodPtr( this, meth._index) Return Byte Ptr meth._index EndIf EndIf Return Null EndFunction Example usage: Local stream:TStream = WriteFile("test") Local StreamWriteLine( this:TStream, s:String) = GetMethodFuncPtr( stream, "WriteLine") StreamWriteLine( stream, "hello") StreamWriteLine( stream, "world") stream.Close() I have an implementation of working method pointers though, using GNU Lightning.. it even plays nicely with the old GC, keeping the object alive until the methodptr is released. But since the language doesnt support them natively, they have to be created and released manually :( Its usage looks something like this: Local stream:TStream = WriteFile("c:\test") Local StreamWriteLine( s:String) = GetMethodPtr( stream, "WriteLine", 1) StreamWriteLine("hello") StreamWriteLine("world") stream.Close() ReleaseMethodPtr(StreamWriteLine) EDIT: If you want to see how it works, download grb.lightning.mod.x86.rar and run this source: |
| ||
@grable bbGCRetain and bbGCRelease have been deprecated, I believe. |
| ||
Method pointers are not possible as Methods allways need an Object to be called. Internaly BRL.Reflection gets a method pointer whenever it invokes a method internaly, but puts the Self-Object on the stack before it calls the method. This is very possible. You can also very easily replace methods. |
| ||
bbGCRetain and bbGCRelease have been deprecated, I believe. Yeah, i havent taken the plunge to 1.32 yet ;) but isnt the old GC still in use when not using threading? |
| ||
Yeah, i havent taken the plunge to 1.32 yet ;) but isnt the old GC still in use when not using threading? Yes. |
| ||
I've been trying to integrate function support into brl.reflection so that it behaves exactly the same as the support for methods, and I've managed to get everything working apart from Invoke(args:Object[]). The code for the whole thing is here http://pastebin.com/f453e43b9 but if you just want to see invoke take a look here.Method Invoke:Object(args:Object[] = Null) Local q[10], sp:Byte Ptr = q sp:+4 If typeId() = LongTypeId sp:+8 ' If args <> Null For Local i = 0 Until args.length If Int Ptr(sp)>=Int Ptr(q)+8 Throw "ERROR" sp = _Push(sp, argTypes()[i], args[i]) Next ' EndIf If Int Ptr(sp)>Int Ptr(q)+8 Throw "ERROR" Select typeId() Case ByteTypeId, ShortTypeId, IntTypeId Local f:Int(p0, p1, p2, p3, p4, p5, p6, p7) = _fptr Return String.FromInt(f(q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7])) Case LongTypeId Throw "TODO" Case FloatTypeId Local f:Float(p0, p1, p2, p3, p4, p5, p6, p7) = _fptr Return String.FromFloat(f(q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7])) Case DoubleTypeId Local f:Double(p0, p1, p2, p3, p4, p5, p6, p7) = _fptr Return String.FromDouble(f(q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7])) Default Local f:Object(p0, p1, p2, p3, p4, p5, p6, p7) = _fptr Return f(q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7]) End Select End Method Field _selfTypeId:TTypeId, _argTypes:TTypeId[] Field _fptr:Byte Ptr Basically, Invoke only seems to work when the function takes no arguments, otherwise the program crashes (no debug information, it just fails). I think if we can fix this, we might have a worthy modification to the official brl.reflection. EDIT: Fixed it myself. Pastebin for the whole working thing is here http://pastebin.com/f5aa00efa . |