Function Pointers and Methods

BlitzMax Forums/BlitzMax Programming/Function Pointers and Methods

Hi, I've been a member here for about 2 years now, so I thought it was time i posted.

I also have come up against something I was hoping to get an answer to. Is it possible for a function pointer to point to a method of a user defined type?

e.g. Is this valid?

Type NewClass
    Field fPointer()

    Method Test()
        Print "Hello"
    End Method
End Type

Local a:NewClass

a=New NewClass
a.fPointer = a.Test
a.fPointer()


I know this is a really trivial example, but I think it illustrates my question.

Well, it doesn't compile...

I don't think so.

Since it doesn't compile I don't think it's possible. When you change the method to a function it does compile though. I'm not sure if it's even possible in any other OOP powered language. Perhaps it's because the method you give doesn't really point to anything. Instead, a memory address is pointing to the object. A method is useless without its object. So I think it's because of that. Since a function is static it's always accessible. If I'm wrong please correct me though.

Some stuff below that might help you on your way with callbacks. It's something I use when implementing the Factory design pattern.

Rem
bbdoc: Function callback
End Rem
Type TFunc
	'The actual function
	Field func:Object(data:Object)
	
	Rem
	bbdoc: Function to create TFunc object
	End Rem
	Function Create:TFunc(func:Object(data:Object))
		Local obj:TFunc = New TFunc
		'Assign function
		obj.func = func
		Return obj
	End Function
End Type

Type TAlliedPlane Extends TAirplaneBase
	Rem
		bbdoc: Create allied airplane
	End Rem
	Method Create:Object(settings:Object = Null)
		Super.Create(settings)
		Return Self
	End Method
	Rem
		bbdoc: Factory function
	End Rem
	Function FactoryFunc:Object(data:Object)
		Return TAlliedPlane(New TAlliedPlane.Create(data))
	End Function
End Type

Local callback:TFunc = TFunc.Create(TAlliedPlane.FactoryFunc)


I haven't posted the code of my TFactory type because it's not really needed here. Anyway, this should show you the, kind of wicked, syntax to accept a function pointer with parameters: Function Create:TFunc(func:Object(data:Object))

No, method pointers aren't valid. They're not valid because methods - at least in BlitzMax - are just functions with a default first parameter which is the instance of the type. A pointer is just a memory address so there's nowhere to store the parameter.

So no, that's not valid. But this is:

Type NewClass
    Field fPointer(C:NewClass)

    Function Test(C:NewClass)
        Print "Hello"
    End Function

End Type

Local a:NewClass

a=New NewClass
a.fPointer = a.Test
a.fPointer(a)



You can of course hack your way around this, just for some fun ;)

test.bmx
Type TTest
	Field Name:String

	Method Message()
		WriteStdout "Hello " + Name + "!~n"
	EndMethod
EndType

run.bmx
Import "Test.bmx"

Extern "c"
	Function Test_Message( this:Byte Ptr) = "_bb_TTest_Message"
EndExtern

Local t:TTest = New TTest
t.Name = "World"
Test_Message Byte Ptr(t) - 8

The reference to a "method" must reside in another unit then the type that has it, or you will get duplicate symbols.

Function Toggle\_Sigma()

Function Toggle\_Sigma()


Very strange.. looks fine in Preview though.

Test\_test\_test

Test\_test\_test


Test_test_test

Test_test_test
'Comment


*Claps*

If you're going to call upon a method using a `fixed` function name, how does it associate with a specific instance of that custom type? How does it know to reference a particular field in a particular instance?

Thanks for the replies guys. I knew what I wrote didn't compile, I thought that maybe I had missed something.

How does it know to reference a particular field in a particular instance?

It doesnt, which is why you have to pass the "this" parameter.
And the generated assembler is hardcoded to the type (it uses relative offsets from this), so passing anything other than itself or its descendants will crash eventually!