ExternalObject

ExternalObject

Information

This information is part of the Modelica Standard Library maintained by the Modelica Association.

Define external functions with internal memory.

Description

External functions may have internal memory reported between function calls. Within Modelica this memory is defined as instance of the predefined class ExternalObject according to the following rules:

  • There is a predefined partial class ExternalObject [since the class is partial, it is not possible to define an instance of this class].
  • An external object class shall be directly extended from ExternalObject, shall have exactly two function definitions, called "constructor" and "destructor", and shall not contain other elements.
  • The constructor function is called exactly once before the first use of the object. For each completely constructed object, the destructor is called exactly once, after the last use of the object, even if an error occurs. The constructor shall have exactly one output argument in which the constructed ExternalObject is returned. The destructor shall have no output arguments and the only input argument of the destructor shall be the ExternalObject. It is not legal to call explicitly the constructor and destructor functions.
  • Classes derived from ExternalObject can neither be used in an extends-clause nor in a short class definition.
  • External functions may be defined which operate on the internal memory of an ExternalObject. An ExternalObject used as input argument or return value of an external C-function is mapped to the C-type "void*".

Examples

A user-defined table may be defined in the following way as an ExternalObject (the table is read in a user-defined format from file and has memory for the last used table interval):

class MyTable
  extends ExternalObject;
  function constructor
    input  String  fileName = "";
    input  String  tableName = "";
    output MyTable table;
    external "C" table = initMyTable(fileName, tableName);
  end constructor;

  function destructor "Release storage of table"
    input  MyTable table;
    external "C" closeMyTable(table);
  end destructor;
end MyTable;

and used in the following way:

model test "Define a new table and interpolate in it"
  MyTable table=MyTable(fileName ="testTables.txt",
                        tableName="table1");  // call initMyTable
  Real y;
equation
  y = interpolateMyTable(table, time);
end test;

This requires to provide the following Modelica function:

function interpolateMyTable "Interpolate in table"
  input  MyTable table;
  input  Real  u;
  output Real  y;
  external "C" y = interpolateMyTable(table, u);
end interpolateTable;

The external C-functions may be defined in the following way:

typedef struct {  /* User-defined data structure of the table */
  double* array;      /* nrow*ncolumn vector       */
  int     nrow;       /* number of rows            */
  int     ncol;       /* number of columns         */
  int     type;       /* interpolation type        */
  int     lastIndex;  /* last row index for search */
} MyTable;

void* initMyTable(const char* fileName, const char* tableName) {
  MyTable* table = malloc(sizeof(MyTable));
  if ( table == NULL ) ModelicaError("Not enough memory");
        // read table from file and store all data in *table
  return (void*) table;
}

void closeMyTable(void* object) { /* Release table storage */
  MyTable* table = (MyTable*) object;
  if ( object == NULL ) return;
  free(table->array);
  free(table);
}

double interpolateMyTable(void* object, double u) {
  MyTable* table = (MyTable*) object;
  double y;
  // Interpolate using "table" data (compute y)
  return y;
}