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() Very strange.. looks fine in Preview though. |
| ||
Test\_test\_testTest\_test\_test |
| ||
Test_test_testTest_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! |
| ||
I'm resurrecting this thread for a bit. Although the following...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) ...seems like a good way to go, it causes issues with garbage collection. I am working on a sprite-driven gui and am using a method similar to the above for handling mouse events. The problem is that the memory for a widget does not get entirely reclaimed if any of the internal functions have been used. Does anyone know how to correct for this? |
| ||
The problem is that the memory for a widget does not get entirely reclaimed if any of the internal functions have been used. What makes you think this is happening? |
| ||
It is probably more accurate to say that the memory does not get reclaimed when I want it to. If I create an instance of the type and then destroy it, the memory is reclaimed. If I create the instance, then run the function, then destroy it, not all of the memory is reclaimed. I presume this is because the function takes the instance as a parameter and is not out of scope. I am looking for a way to get around that. |
| ||
If I create the instance, then run the function, then destroy it, not all of the memory is reclaimed. I presume this is because the function takes the instance as a parameter and is not out of scope. I am looking for a way to get around that. That makes no sense at all. If the instance is stored no where when you toss it off to the function it should have no consequence. |
| ||
The instance is stored when the function is called, but then I want to get rid of the instance and end up with the same memory allocated as when I started. I apologize if I'm not explaining this very well... |
| ||
I have apparently misdiagnosed the problem. I created a simpler test that works fine. :( |