ModelicaSpecification icon indicating copy to clipboard operation
ModelicaSpecification copied to clipboard

Specify external function argument mapping for records

Open henrikt-ma opened this issue 3 years ago • 2 comments

This issue is extracted from a discussion in #3130 (see https://github.com/modelica/ModelicaSpecification/pull/3130#issuecomment-1109557559 and related comments). In that PR it is clarified how nested records should be stored when passed to or from an external function.

This issue is about specifying what type to use in a prototype for the external function (as well as in its implementation, but that's outside the scope of the specification).

To make picky compilers happy, there seems to be no realistic alternative to passing records as void const*, and returning them through a void*.

(A crazy alternative would be to specify exactly what the name of the struct should be, as well as the exact names of all (nested) struct members. This would allow the generated code for calling the external function to populate a struct defined in the same header that gives the prototype for the external function.)

henrikt-ma avatar Apr 26 '22 10:04 henrikt-ma

Just to be clear - this is not such a major issue as in most cases records can be avoided by sending individual members of the record to the external function instead. This is additionally necessary to handle arrays in records, and thus the number of external functions directly using records isn't that high.

However, using void* is a really bad idea as you abandon all type-checking just to avoid some of them, and it would introduce a compatibility issue with existing code.

Given that there are basically two cases for external functions:

  • You just link with it. That should normally work.
  • You include the C-code. The assumption is that the C-code declares the function.

In the latter, problematic, case I see two possibilities:

  • The names of the structs used by the C-code are reported back to the Modelica code and then used. This will require additions to the standard, updates of libraries, and creates problems if multiple functions have compatible records.
  • Casting: one can in C convert the user-function to an appropriate function-pointer using a cast, and then call that. I'll have to investigate more whether it merely works, or whether there are some general strict guarantees that it works.

Note that the casting is something that can be done internally in tools, without any changes in the specification. I thus view this as primarily a tool issue. It will require a small update as that casting assumes that C-function is an actual function (and not a macro) with compatible types (so no implicit type conversions based on the prototype).

HansOlsson avatar May 04 '22 07:05 HansOlsson

Just adding a comment to let you know that I have read through the discussions here as well as in #3155. I am just checking with my colleagues before formulating my thoughts.

eshmoylova avatar May 06 '22 18:05 eshmoylova