Page 1 of 1
Assigning structure address to Interface invalid memory access error
Posted: Fri Apr 23, 2021 12:33 pm
by devox
Hi,
I'm experimenting with some of the OOP like features in PB, and I'm following Drac's tutorials on the subject (
http://drac.site.chez-alice.fr/Tutorial ... ace_en.htm).
I have this basic bit of code
Code: Select all
Interface IPerson
Display()
EndInterface
Structure PersonMethods
*Display
EndStructure
Procedure Person_Display()
Debug "Display Called"
EndProcedure
PersonImp.PersonMethods
PersonImp\Display = @Person_Display()
Debug "Calling Display() using Implementation pointer"
CallFunctionFast(PersonImp\Display)
Debug ""
Person.IPerson = @PersonImp
Debug "Calling Display() using Interface"
Person\Display()
But when I run it the last call on Person\Display() causes a runtime error of invalid memory address? I am able to call the method via CallFunctionFast with the function pointer though?
Re: Assigning structure address to Interface invalid memory access error
Posted: Fri Apr 23, 2021 2:41 pm
by Bisonte
Here is a "skeleton" for using own interfaces I'am using (edit it for your test person):
Code: Select all
DeclareModule Person
EnableExplicit
Interface iPerson
SetName(Name.s)
GetName.s()
SetAge(Age)
GetAge()
Display()
Destroy()
EndInterface
Declare.i CreatePerson(Name.s)
EndDeclareModule
Module Person
Structure obj
vTable.i ; virtual table must be the first entry !!
Name.s
Age.i
EndStructure
; -- Methods
; =============================================================================
Procedure.i SetName(*this.obj, Name.s)
If *this
*this\Name = Name
EndIf
EndProcedure
Procedure.s GetName(*this.obj)
Protected Result.s = ""
If *this
Result = *this\Name
EndIf
ProcedureReturn Result
EndProcedure
Procedure.i SetAge(*this.obj, Age)
If *this
*this\Age = Age
EndIf
EndProcedure
Procedure.i GetAge(*this.obj)
Protected Result.i
If *this
Result = *this\Age
EndIf
ProcedureReturn Result
EndProcedure
Procedure.i Display(*this.obj)
If *this
Debug "Person Data"
Debug "-----------"
Debug "Name : " + *this\Name
Debug "Age : " + *this\Age
Debug "==========="
EndIf
EndProcedure
Procedure.i DestroyObject(*this.obj)
FreeStructure(*this) : *this = #Null
ProcedureReturn *this
EndProcedure
; -- Public
Procedure.i CreatePerson(Name.s)
Protected *this.obj = AllocateStructure(obj)
If *this
*this\vTable = ?vTable_iPerson
*this\Name = Name
EndIf
ProcedureReturn *this
EndProcedure
; -- Virtual Table
; =============================================================================
; the order of the Methods must be the same like in Interface-EndInterface !
DataSection
vTable_iPerson:
Data.i @SetName()
Data.i @GetName()
Data.i @SetAge()
Data.i @GetAge()
Data.i @Display()
Data.i @DestroyObject()
EndDataSection
EndModule
UseModule Person
; Demo
Person1.iPerson = CreatePerson("Devox")
Person1\SetAge(20)
Person1\Display()
Person1\Destroy()
In your example you can only use Methods without parameters... and Callfunction... you should not use it, because it is very error-prone !
Prototype is the keyword for search in PB-Manual, if you want to use CallFunction or CallFunctionFast ...
Re: Assigning structure address to Interface invalid memory access error
Posted: Fri Apr 23, 2021 3:08 pm
by devox
@Bisonte, thank you very much that is extremely helpful.

Re: Assigning structure address to Interface invalid memory access error
Posted: Sat Apr 24, 2021 1:38 am
by Bisonte
The examples from mk-soft helped me a lot... Thanks go to him

Re: Assigning structure address to Interface invalid memory access error
Posted: Sat Apr 24, 2021 2:40 am
by StarBootics
It's a very old sets of tutorials. That being said if you want to really experiment some OOP with PureBasic I suggest to download, study and compile for your self
Dev-Object that can write code like that in matter of milliseconds. For example :
Code: Select all
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; AUTOMATICALLY GENERATED CODE, DO NOT MODIFY
; UNLESS YOU REALLY, REALLY, REALLY MEAN IT !!
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Code generated by : Dev-Object - V1.4.5
; Project name : the project name here
; File name : File name here
; File Version : 0.0.0
; Programmation : In progress
; Programmed by : StarBootics
; Creation Date : 23-04-2021
; Last update : 23-04-2021
; Coded for PureBasic : V5.73 LTS
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
DeclareModule Person
Interface Person
GetName.s()
GetAge.l()
SetName(P_Name.s)
SetAge(P_Age.l)
Update(P_Name.s, P_Age.l)
Reset()
Copy.i()
Free()
EndInterface
; Declare Free(*This)
Declare.i New(P_Name.s = "", P_Age.l = 0)
EndDeclareModule
Module Person
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Structure declaration <<<<<
Structure Private_Members
VirtualTable.i
Name.s
Age.l
EndStructure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The observators <<<<<
Procedure.s GetName(*This.Private_Members)
ProcedureReturn *This\Name
EndProcedure
Procedure.l GetAge(*This.Private_Members)
ProcedureReturn *This\Age
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The mutators <<<<<
Procedure SetName(*This.Private_Members, P_Name.s)
*This\Name = P_Name
EndProcedure
Procedure SetAge(*This.Private_Members, P_Age.l)
*This\Age = P_Age
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The Update operator <<<<<
Procedure Update(*This.Private_Members, P_Name.s, P_Age.l)
*This\Name = P_Name
*This\Age = P_Age
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The Reset operator <<<<<
Procedure Reset(*This.Private_Members)
*This\Name = ""
*This\Age = 0
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The Copy operator <<<<<
Procedure.i Copy(*This.Private_Members)
*Copy.Private_Members = AllocateStructure(Private_Members)
*Copy\VirtualTable = ?START_METHODS
*Copy\Name = *This\Name
*Copy\Age = *This\Age
ProcedureReturn *Copy
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The Destructor <<<<<
Procedure Free(*This.Private_Members)
FreeStructure(*This)
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The Constructor <<<<<
Procedure.i New(P_Name.s = "", P_Age.l = 0)
*This.Private_Members = AllocateStructure(Private_Members)
*This\VirtualTable = ?START_METHODS
*This\Name = P_Name
*This\Age = P_Age
ProcedureReturn *This
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The Virtual Table Entries <<<<<
DataSection
START_METHODS:
Data.i @GetName()
Data.i @GetAge()
Data.i @SetName()
Data.i @SetAge()
Data.i @Update()
Data.i @Reset()
Data.i @Copy()
Data.i @Free()
END_METHODS:
EndDataSection
EndModule
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Code generated in : 00.001 seconds (154000.00 lines/second) <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
Best regards
StarBootics
Re: Assigning structure address to Interface invalid memory access error
Posted: Sat Apr 24, 2021 8:40 am
by devox
StarBootics wrote: Sat Apr 24, 2021 2:40 am
It's a very old sets of tutorials. That being said if you want to really experiment some OOP with PureBasic I suggest to download, study and compile for your self
Dev-Object that can write code like that in matter of milliseconds.
I had a feeling what I was doing maybe out of date, found that problem a few times whilst learning PB. Your tool looks just brilliant and really helpful with this I will be sure to give it a try.
Many thanks
Re: Assigning structure address to Interface invalid memory access error
Posted: Sat Apr 24, 2021 12:07 pm
by mk-soft
If you then start with external interfaces (Windows COM Objects), that the parameter passing and just the return of the result of a method looks a little different.
The result of a method is then always whether the method was successfully executed and for the return value a pointer must be passed in the parameter.
If you are interested, you can also have a look at OOP-BaseClass and, if you are ready, at OOP-BaseClassDispatch for creating DLLs externally.