Skip to content

Propose complete handling of records in external functions. #3198

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions chapters/functions.tex
Original file line number Diff line number Diff line change
Expand Up @@ -2220,6 +2220,11 @@ \subsubsection{Records}\label{records}
\begin{itemize}
\item
The record class is represented by a struct in C.
\item
If the record has \lstinline!annotation(CStructName="CName")! the struct has the name CName, \cref{annotations-for-records-in-external-functions}.
\item
If the record has \lstinline!annotation(Include="includeDirective")! it is assumed that the include directive will declare the struct, \cref{annotations-for-records-in-external-functions}.
Without \lstinline!annotation(CStructName="CName")! it is assumed that the name of the struct is the same as the record-class.
\item
Each component of the Modelica record is mapped to its corresponding C representation.
A nested record component is mapped to a nested struct component.
Expand Down Expand Up @@ -2562,6 +2567,30 @@ \subsection{Annotations for External Functions}\label{annotations-for-external-l

The \lstinline!Library! name and the \lstinline!LibraryDirectory! name in the function annotation are mapped to a linkage directive in a compiler-dependent way thereby selecting the object library suited for the respective computer platform.

\subsection{Annotations for Records in External Functions}\label{annotations-for-records-in-external-functions}
Records used in external functions may have the following annotations.

The following annotations are useful in the context of records used in calling external functions from Modelica.
The first two can specify either a scalar value or an array of values:
\begin{itemize}
\item
The \lstinline!annotation(Include="includeDirective")!\annotationindex{Include}, used to include source files needed for declaring the struct in C.
The included code should be valid C89 code.
It should declare the struct-members in C, but they may be aligned differently, they may be in a different order, and additional padding or fields may exist.
\begin{nonnormative}
Examples of files that can be included are header files or source files that contain the struct declaration corresponding to the Modelica record.
In this case the consistency is ensured by including the correct definition and thus the contents is freer, whereas the struct generated by tools must be restricted to ensure consistency.
\end{nonnormative}
\item
The
\lstinline!annotation(IncludeDirectory="modelica://ModelicaLibraryName/Resources/Include")!\annotationindex{IncludeDirectory}, used to specify a location for header files.
The preceding one is the default and need not be specified; but another location could be specified by using an URI name for the include directory, see \cref{external-resources}.
\item
The \lstinline!annotation(CStructName="CName")!\annotationindex{CStructName} gives the name of the struct in C.
It requires that the name of the struct-members in C are the same as in Modelica.
\end{itemize}
The includeDirective is only included if the record is used in an external function call used in the simulation model.
If multiple record definitions used in this way have the same \lstinline!CName! it is an error unless the records are type compatible.
\subsection{Examples}\label{examples1}

\subsubsection{Input Parameters, Function Value}\label{input-parameters-function-value}
Expand Down Expand Up @@ -2653,6 +2682,39 @@ \subsubsection{Both Function Value and Output Variable}\label{external-function-
\end{lstlisting}
\end{example}

\subsubsection{Record example}\label{record-example}

\begin{example}
The following external function illustrates the annotations in \cref{annotations-for-records-in-external-functions}.
It assumes that the external code uses \lstinline!MyComp_! as a prefix for declarations to avoid namespace collisions.
\begin{lstlisting}[language=modelica]
record R
Real x;
Integer y;
annotation(CStructName="MyComp_R");
end R;
record R2
Real z;
Real w;
annotation(Include="struct MyComp_R2 {double a,w,z;}");
// Note different order and a is unused.
end R2;
function foo
input R r;
input output R2 r2;
external "C"
MyComp_foo(r, r2);
annotation(Include="void MyComp_foo(const struct MyComp_R*r, struct MyComp_R2*r2);");
end foo;
\end{lstlisting}
This will generate C-code along these lines:
\begin{lstlisting}[language=C]
struct MyComp_R2 {double a,w,z;}
struct MyComp_R {double x;int y;}
void MyComp_foo(const struct MyComp_R*r, struct MyComp_R2*r2);
\end{lstlisting}
\end{example}

\subsection{Utility Functions}\label{utility-functions}

This section describes the utility functions declared in \filename{ModelicaUtilities.h}, which can be called in external Modelica functions written in C.
Expand Down