Using C Functions and Constants

You can use C constants and functions defined in an external DLL within a LCM program.

Extern elements can be types, constants or functions.

In order to simulate or debug LCM programs that include external c definitions, the LCM interpreter needs to link dynamically with libraries providing these definitions.

Having extern elements in an LCM program consists in declaring them with their signature, and link them with their name in the host language. This is a two-facets and semi-automated process.

First you define signatures of extern elements that you use in the implementation of your LCM program, with the benefit of the LCM type inference.

The next step, basically done for simulation purposes with a virtual machine, consists in adapting your functions implementation with a generated stub generated, in order to have correct type correspondences.

The example used here consists in using as externs in an LCM program the following terms implemented in c:


  • the Napier constant, e , having the prototype:

const double e = 2.71828182845905;


  • a function Generation, generating random events, having the prototype:

double Generation();


  • a function uniform, computing a uniform law. Its prototype is:

int Uniform ();


  • a function Normal computing a normal law:

double Normal (int m,int s);


Before you begin:
  • The Device Logic Design or the Module & Block For Library workbench should be opened.
  • The State Logic Modeling or the Module & Block For Library workbench should be opened.
  1. To define an Extern function, click New Extern Function .

    The Extern Function Definition dialog box appears:



    Fill the Name field with the name of the function that is known for the LCM program. In the External Function area, set names and parameters types that are LCM type equivalences of C types used in your C header file.

    Important: In order to easily map the C and LCM types, you must respect the following rules:
    • The parameter of the function must be a simple type element or a tuple of simple type elements.
    • The result of the function must be a simple type element.

    A simple type is not a structure, an alias or a tuple. That is to say it is a predefined type (see Predefined Types and Functions).

    Note that a function with no parameter should be declared with the type pure as parameter (this is the case for the Generation and Uniform functions).

    Here is the LCM signature of the function Generation:



    and Uniform:



    For these 2 functions, the parameter and the result of the function are simple type elements.

    The LCM parameter for the function

    Normal

    is defined as a tuple of simple type elements.

    Here is the signature that has been chosen for the function

    Normal



    The Extern Function Definition dialog box is filled like this:



  2. To define an Extern constant, click New Extern Constant .

    The Extern Constant Definition dialog box appears.



    In the Properties area, set the name of the constant that is known for the LCM program.

    In the Extern Constant area, enter the name as known in the host language, and set its type.

    For the constant e, the dialog box is filled as follows.



  3. You can use extern definitions in the LCM program as follows.

    Extern elements can be used just like internals, using the same syntax.

    The example below shows how previous declared functions and constants are used in SFC+. Extern functions are called in SFC+ actions.



    Note that LCM terms used as parameters and results of these functions are inferred.

  4. Generating stubs and building dynamic libraries.

    Right-click the root module of the LCM logic (State Logic Behavior or Simulation Logic) in the tree, and select Tools > Generate Stub: The Stub Generation dialog window appears.

    The Name field takes the name of your Control Logic, and the Directory field is where the files are to be generated.

    If Template is selected, a tree structure like in Visual Studio will be generated.

    If Back Up Files is selected, the generation will not overwrite files from a previous generation, they will be renamed.

    Click OK: a window listing all the files and directories to be created appears. You can select and de-select them in the left column if needed.



    Click OK: a confirmation window pops up.

    Tip: You can find an implementation of the functions used as example in this chapter in a Visual Studio project located at
    <Delmia Automation path>\intel_a\resources\lcmexternlib\EXTERNS.zip

    In the include directory, open the header file my_workspace_name.h (for example, EXTERNS.h) and insert the prototype of your function and constant definitions where you find the c comment:

    /*Add prototype of external functions...*/

    The prototype of the function must be changed to match the LCM types. For instance, the prototype of the Normal function is defined as follows:

    LCMFloat64 Normal(LCMInt32 m, LCMInt32 s)

    In the source directory, open the file my_workspace_name.cpp (for example, EXTERNS.cpp) and insert the implementation of your functions where you find the c comment:

    /*Define here functions implement*/

    Compile all source files and link them inside a library having the name of your Logic workspace.

  5. Setting simulation properties.

    The path of the DLL is a property of the Simulation Logic for smart ressources or a property of the library.

    Select Properties in the contextual menu of the State Logic Library and check that the path of the DLL used by the simulation is correct.



    You can have several libraries to use for a simulation. You can include several Windows paths, separating them by a semi-colon.