[Contents] [TitleIndex] [WordIndex

Emulate Object Oriented in Scilab - part 3

Abstract

The current version of the Scilab language is procedural. The goal of this page is to show how to make a OO-like system in Scilab, based on the SCILAB_POINTER_DATATYPE data type.

Introduction

That method has been re-discovered by Antoine Elias recently. Apparently, it was developped to create an interface for sparse linear algebra. I made some modifications to the source code produced by Antoine to meet my needs to emulate OO in Scilab.

See in attachment scipointer-v0.2.zip for a .zip which contains the full toolbox, validated on Windows.

On the use of Scilab pointers

I make the hypothesis that I have a C++ class, "MyClass", which has 3 members : type, a, b and possess a "print" method. The goal is to be able to write in the Scilab console :

vu1 = myclass_new("Normale",1.0,0.5);
myclass_print(vu1);
myclass_destroy(vu1);

At the core of the method is the Scilab data type SCILAB_POINTER_DATATYPE. To create such a variable, one simply use the CreateVarFromPtr function, extracted from sci_myclass_new.cpp :

myobject = new MyClass(name, parameter1[0], parameter2[0]);
CreateVarFromPtr(Rhs + 1, SCILAB_POINTER_DATATYPE , &iRows, &iCols, (void*)myobject); /* Note that this code is deprecated and should be replaced by API_Scilab */

When the print method is to be called, on first get a pointer to the location in the stack where the real pointer is stored. Then, one cast back the pointer into the real class data type. This is done in the following source code, extracted from sci_myclass_print.cpp :

GetRhsVar(1, SCILAB_POINTER_DATATYPE, &iRows, &iCols, &iStackPointer); /* Note that this code is deprecated and should be replaced by API_Scilab */
myobject = (MyClass*)((unsigned long int) *stk(iStackPointer));
myobject->Print();

The destructor is based on the same method, but, this time, the "free" command is called. The following source code is extracted from sci_myclass_destroy.cpp :

GetRhsVar(1, SCILAB_POINTER_DATATYPE, &iRows, &iCols, &iStackPointer); /* Note that this code is deprecated and should be replaced by API_Scilab */
myobject = (MyClass*)((unsigned long int) *stk(iStackPointer));
free(myobject);

The following script shows how to use these methods from the Scilab language :

vu1 = myclass_new("Normale",1.0,0.5);
// Look in the real console ! (F12 under Windows)
myclass_print(vu1);
myclass_destroy(vu1);

There is no difficulty to create the gateways.

The following is a list of advantages / drawbacks.

Advantages

Drawbacks

Suppose that two objects are implemented with this method, say "a" for "myclass" and "b" for "mybetterclass". Now, if you pass the token "b" to a method of the class "myclass", it is very probable that the integer a will index an existing position in the hash map, i.e. the method will have an unexpected effect, but will not generate an error. Respectively, it may index a position which does not exist. That may lead to bugs difficult to analyse.


2022-09-08 09:27