I'm not sure if what I am doing is correct or if I have found a bug, I would like for someone else to please test this code.
This example program creates an interface and a structure and then instantiates an "object" using a virtual table.
The object is very simple and all it does is set/get a number and a string.
I can instantiate the object and set both the number and the string just fine, I can get the value of the number just fine however I'm having problems with the string, I can set it but not read it as such.
The problem occurs when calling the function: "Thing_Get_Str" / GetStr() via the object's interface.
When I call the function rather than getting a string I get the address of the string, also if multiple calls are made to the function it crashes complaining about invalid memory access.
I have written this on PB 6.0 on Ubuntu Linux 20.04
If someone could please give it a go and see if I've done something wrong, I have been banging my head against the keyboard for the entire evening trying to find what is wrong.

Code: Select all
EnableExplicit
Declare.i main()
OpenConsole()
;- 1_Class Declaration - Thing
; Data for the class
Structure cls_ClassThing
*virtualtable ; pointer to function virtual table as first entry
int_Number.i
str_String.s
EndStructure
; Public methods
Procedure Thing_Set_Num(*Self.cls_ClassThing, int_value.i) ;first parameter is the *Self pointer
*Self\int_Number = int_value
EndProcedure
Procedure Thing_Get_Num(*Self.cls_ClassThing)
ProcedureReturn *Self\int_Number
EndProcedure
Procedure Thing_Set_Str(*Self.cls_ClassThing, str_string.s) ;first parameter is the *Self pointer
*Self\str_String = str_string
EndProcedure
Procedure.s Thing_Get_Str(*Self.cls_ClassThing)
;Debug(*Self\str_String)
ProcedureReturn *Self\str_String.s
EndProcedure
; Destructor
Procedure Thing_Destroy(*Self.cls_ClassThing)
FreeMemory(*Self)
EndProcedure
; Interface definition
Interface iface_Thing ; create interface hides the *Self pointer
GetNum()
SetNum(int_value.i)
GetStr()
SetStr(str_string.s)
Destroy()
EndInterface
; Virtual Function table
DataSection
vtThing: ; create virtual table
Data.i @Thing_Get_Num()
Data.i @Thing_Set_Num()
Data.i @Thing_Get_Str()
Data.i @Thing_Set_Str()
Data.i @Thing_Destroy()
EndDataSection
; Contructor
Procedure New_Thing()
Protected *Self.cls_ClassThing
*Self = AllocateMemory(SizeOf(cls_ClassThing))
If *Self
*Self\virtualtable = ?vtThing
ProcedureReturn *Self
EndIf
EndProcedure
; Object instantiation
Global *obj_Thing.iface_Thing = New_Thing()
If *obj_Thing
*obj_Thing\SetNum(9876543210)
*obj_Thing\SetStr("Hello from the world")
EndIf
;- 2_Procedures
Procedure.i main()
Define str_keypress.s
PrintN("Object Number = " + Str(*obj_Thing\GetNum()))
Debug(*obj_Thing\GetStr()) ; - Returns string address rather than string, is this a bug or the expected behaviour?
Debug(PeekS(*obj_Thing\GetStr())) ; - Prints the string correctly
; Define var = *obj_Thing\GetStr() ; *** uncomment this line to get a crash, is this a bug? ***
PrintN("Object String = " + *obj_Thing\GetStr()) ; Prints the string plus the memory address in numeric format, is this a bug?
PrintN(Chr(10) + "Press esc to exit")
Repeat
Delay(20)
str_keypress = Inkey()
Until str_keypress = Chr(27)
*obj_Thing\Destroy()
End
EndProcedure
main()