How about this little workaround/hack?
SuperStrict
Framework brl.standardio
Import brl.reflection
Function testFunction:String(str:String)
Return "testFunction(~q"+str+"~q)"
EndFunction
Type TTestType
Method testMethod:String(str:String)
Return "testMethod(~q"+str+"~q)"
EndMethod
EndType
Local functionDelegate:TDelegate=New TFunctionDelegate.create(testFunction,StringTypeId,[StringTypeId])
Local methodDelegate:TDelegate=New TMethodDelegate.create(New TTestType,"testMethod")
Print String(functionDelegate.call(["test"]))
Print String(methodDelegate.call(["test"]))
Rem
Definitions
EndRem
Type TDelegate Abstract
Method call:Object(args:Object[]=Null) Abstract
EndType
Type TMethodDelegate Extends TDelegate
Field this:Object
Field methodPtr:TMethod
Method Delete()
this=Null
methodPtr=Null
EndMethod
Method Create:TDelegate(this:Object,name:String)
If Not this Return Null
Local id:TTypeId=TTypeId.ForObject(this)
self.methodPtr=id.findMethod(name)
If Not self.methodPtr Return Null
self.this=this
Return Self
EndMethod
Method call:Object(args:Object[]=Null)
Return methodPtr.invoke(this,args)
EndMethod
EndType
Type TFunctionDelegate Extends TDelegate
Field functionPtr:Byte Ptr
Field returnType:TTypeId
Field argTypes:TTypeId[]
Method Delete()
functionPtr=Null
returnType=Null
argTypes=Null
EndMethod
Method Create:TFunctionDelegate(functionPtr:Byte Ptr,returnType:TTypeId,argTypes:TTypeId[])
self.functionPtr=functionPtr
self.returnType=returnType
self.argTypes=argTypes
Return Self
EndMethod
Method call:Object(args:Object[]=Null)
Return _Call(functionPtr,returnType,args,argTypes)
EndMethod
EndType
Private ' brl.reflection
Extern
Function bbRefPushObject(p:Byte Ptr,obj:Object)
Function bbRefGetObjectClass(obj:Object)
Function bbRefGetSuperClass(class:Int)
EndExtern
Function _Push:Byte Ptr( sp:Byte Ptr,typeId:TTypeId,value:Object )
Select typeId
Case ByteTypeId,ShortTypeId,IntTypeId
(Int Ptr sp)[0]=value.ToString().ToInt()
Return sp+4
Case LongTypeId
(Long Ptr sp)[0]=value.ToString().ToLong()
Return sp+8
Case FloatTypeId
(Float Ptr sp)[0]=value.ToString().ToFloat()
Return sp+4
Case DoubleTypeId
(Double Ptr sp)[0]=value.ToString().ToDouble()
Return sp+8
Case StringTypeId
If Not value value=""
bbRefPushObject sp,value
Return sp+4
Default
If value
Local c:Int=typeId._class
Local t:Int=bbRefGetObjectClass( value )
While t And t<>c
t=bbRefGetSuperClass( t )
Wend
If Not t Throw "ERROR"
EndIf
bbRefPushObject sp,value
Return sp+4
End Select
End Function
Function _Call:Object( p:Byte Ptr,typeId:TTypeId,args:Object[],argTypes:TTypeId[] )
Local q:Int[10],sp:Byte Ptr=q
If typeId=LongTypeId sp:+8
For Local i:Int=0 Until args.length
If Int Ptr(sp)>=Int Ptr(q)+8 Throw "ERROR"
sp=_Push( sp,argTypes[i],args[i] )
Next
If Int Ptr(sp)>Int Ptr(q)+8 Throw "ERROR"
Select typeId
Case ByteTypeId,ShortTypeId,IntTypeId
Local f(p0:Int,p1:Int,p2:Int,p3:Int,p4:Int,p5:Int,p6:Int,p7:Int)=p
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:Int,p1:Int,p2:Int,p3:Int,p4:Int,p5:Int,p6:Int,p7:Int)=p
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:Int,p1:Int,p2:Int,p3:Int,p4:Int,p5:Int,p6:Int,p7:Int)=p
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:Int,p1:Int,p2:Int,p3:Int,p4:Int,p5:Int,p6:Int,p7:Int)=p
Return f( q[0],q[1],q[2],q[3],q[4],q[5],q[6],q[7] )
End Select
EndFunction
Just had to remove the obj-reference-push in the _Call Function from the Reflection Module.
- FOODy