]> gerrit.simantics Code Review - simantics/fmil.git/blobdiff - org.simantics.fmil.core/native/FMILibrary/src/CAPI/src/FMI2/fmi2_capi.c
Add FMILibrary-2.0.3 to org.simantics.fmil.core\native.
[simantics/fmil.git] / org.simantics.fmil.core / native / FMILibrary / src / CAPI / src / FMI2 / fmi2_capi.c
diff --git a/org.simantics.fmil.core/native/FMILibrary/src/CAPI/src/FMI2/fmi2_capi.c b/org.simantics.fmil.core/native/FMILibrary/src/CAPI/src/FMI2/fmi2_capi.c
new file mode 100644 (file)
index 0000000..06d27c4
--- /dev/null
@@ -0,0 +1,494 @@
+/*
+    Copyright (C) 2012 Modelon AB
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the BSD style license.
+
+     This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    FMILIB_License.txt file for more details.
+
+    You should have received a copy of the FMILIB_License.txt file
+    along with this program. If not, contact Modelon AB <http://www.modelon.com>.
+*/
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <assert.h>
+
+#include <JM/jm_types.h>
+#include <JM/jm_portability.h>
+
+#include <FMI2/fmi2_capi_impl.h>
+
+#define FUNCTION_NAME_LENGTH_MAX 2048                  /* Maximum length of FMI function name. Used in the load DLL function. */
+#define STRINGIFY(str) #str
+
+/* Loading shared library functions */
+static jm_status_enu_t fmi2_capi_get_fcn(fmi2_capi_t* fmu, const char* function_name, jm_dll_function_ptr* dll_function_ptrptr, jm_status_enu_t* status )
+{
+               jm_status_enu_t jm_status = jm_portability_load_dll_function(fmu->dllHandle, (char*)function_name, dll_function_ptrptr);
+               if (jm_status == jm_status_error) {
+                       jm_log_error(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Could not load the FMI function '%s'. %s", function_name, jm_portability_get_last_dll_error()); 
+                       *status = jm_status_error;
+               }
+               return jm_status;
+}
+
+static void fmi2_capi_get_fcn_with_flag(fmi2_capi_t* fmu, const char* function_name, 
+                                                                                                       jm_dll_function_ptr* dll_function_ptrptr, 
+                                                                                                       unsigned int capabilities[],
+                                                                                                       fmi2_capabilities_enu_t flag) {
+       jm_status_enu_t status = jm_status_success;
+       if(capabilities[flag]) {
+               fmi2_capi_get_fcn(fmu, function_name, dll_function_ptrptr, &status);
+               if(status != jm_status_success) {
+                       jm_log_warning(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Resetting flag '%s'", fmi2_capability_to_string(flag)); 
+                       capabilities[flag] = 0;
+               }
+       }
+}
+
+/* Load FMI functions from DLL macro */
+#define LOAD_DLL_FUNCTION(FMIFUNCTION) fmi2_capi_get_fcn(fmu, #FMIFUNCTION, (jm_dll_function_ptr*)&fmu->FMIFUNCTION, &jm_status)
+
+/* Load FMI functions from DLL macro for functions controlled by capability flags */
+#define LOAD_DLL_FUNCTION_WITH_FLAG(FMIFUNCTION, FLAG) \
+       fmi2_capi_get_fcn_with_flag(fmu, #FMIFUNCTION, (jm_dll_function_ptr*)&fmu->FMIFUNCTION, capabilities, FLAG)
+
+static jm_status_enu_t fmi2_capi_load_common_fcn(fmi2_capi_t* fmu, unsigned int capabilities[])
+{
+       jm_status_enu_t jm_status = jm_status_success;
+       /***************************************************\r
+Types for Common Functions\r
+****************************************************/\r
+\r
+/* Inquire version numbers of header files and setting logging status */\r
+/*   typedef const char* fmi2GetTypesPlatformTYPE(void);\r
+   typedef const char* fmi2GetVersionTYPE(void);\r
+   typedef fmi2Status  fmi2SetDebugLoggingTYPE(fmi2Component, fmi2Boolean, size_t, const fmi2String[]); */\r
+\r
+       LOAD_DLL_FUNCTION(fmi2GetTypesPlatform);
+       LOAD_DLL_FUNCTION(fmi2GetVersion);
+       LOAD_DLL_FUNCTION(fmi2SetDebugLogging);
+
+/* Enter and exit initialization mode, terminate and reset */
+/* typedef fmi2Status fmi2TerminateTYPE              (fmi2Component);
+   typedef fmi2Status fmi2ResetTYPE                  (fmi2Component); */
+       LOAD_DLL_FUNCTION(fmi2Terminate);
+       LOAD_DLL_FUNCTION(fmi2Reset);
+
+    /* Creation and destruction of instances and setting debug status */
+    /*typedef fmi2Component fmi2InstantiateTYPE (fmi2String, fmi2Type, fmi2String, fmi2String, const fmi2CallbackFunctions*, fmi2Boolean, fmi2Boolean);
+    typedef void          fmi2FreeInstanceTYPE(fmi2Component);*/
+    LOAD_DLL_FUNCTION(fmi2Instantiate);
+    LOAD_DLL_FUNCTION(fmi2FreeInstance);
+
+   /* typedef fmi2Status fmi2SetupExperimentTYPE        (fmi2Component, fmi2Boolean, fmi2Real, fmi2Real, fmi2Boolean, fmi2Real);
+   typedef fmi2Status fmi2EnterInitializationModeTYPE(fmi2Component);
+   typedef fmi2Status fmi2ExitInitializationModeTYPE (fmi2Component); */
+    LOAD_DLL_FUNCTION(fmi2SetupExperiment);
+    LOAD_DLL_FUNCTION(fmi2EnterInitializationMode);
+    LOAD_DLL_FUNCTION(fmi2ExitInitializationMode);
+
+       /* Getting and setting variable values */\r
+/*   typedef fmi2Status fmi2GetRealTYPE   (fmi2Component, const fmi2ValueReference[], size_t, fmi2Real   []);\r
+   typedef fmi2Status fmi2GetIntegerTYPE(fmi2Component, const fmi2ValueReference[], size_t, fmi2Integer[]);\r
+   typedef fmi2Status fmi2GetBooleanTYPE(fmi2Component, const fmi2ValueReference[], size_t, fmi2Boolean[]);\r
+   typedef fmi2Status fmi2GetStringTYPE (fmi2Component, const fmi2ValueReference[], size_t, fmi2String []); */\r
+\r
+       LOAD_DLL_FUNCTION(fmi2GetReal);
+       LOAD_DLL_FUNCTION(fmi2GetInteger);
+       LOAD_DLL_FUNCTION(fmi2GetBoolean);
+       LOAD_DLL_FUNCTION(fmi2GetString);
+\r
+       /*   typedef fmi2Status fmi2SetRealTYPE   (fmi2Component, const fmi2ValueReference[], size_t, const fmi2Real   []);\r
+   typedef fmi2Status fmi2SetIntegerTYPE(fmi2Component, const fmi2ValueReference[], size_t, const fmi2Integer[]);\r
+   typedef fmi2Status fmi2SetBooleanTYPE(fmi2Component, const fmi2ValueReference[], size_t, const fmi2Boolean[]);\r
+   typedef fmi2Status fmi2SetStringTYPE (fmi2Component, const fmi2ValueReference[], size_t, const fmi2String []); */\r
+\r
+       LOAD_DLL_FUNCTION(fmi2SetReal);
+       LOAD_DLL_FUNCTION(fmi2SetInteger);
+       LOAD_DLL_FUNCTION(fmi2SetBoolean);
+       LOAD_DLL_FUNCTION(fmi2SetString);
+\r
+       return jm_status;
+}
+
+/* Load FMI 2.0 Co-Simulation functions */
+static jm_status_enu_t fmi2_capi_load_cs_fcn(fmi2_capi_t* fmu, unsigned int capabilities[])
+{
+       jm_status_enu_t jm_status = jm_status_success;
+
+       jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Loading functions for the co-simulation interface"); 
+
+       jm_status = fmi2_capi_load_common_fcn(fmu, capabilities);
+
+       /* Getting and setting the internal FMU state */\r
+/*   typedef fmi2Status fmi2GetFMUstateTYPE           (fmi2Component, fmi2FMUstate*);\r
+   typedef fmi2Status fmi2SetFMUstateTYPE           (fmi2Component, fmi2FMUstate);\r
+   typedef fmi2Status fmi2FreeFMUstateTYPE          (fmi2Component, fmi2FMUstate*);\r
+   typedef fmi2Status fmi2SerializedFMUstateSizeTYPE(fmi2Component, fmi2FMUstate, size_t*);\r
+   typedef fmi2Status fmi2SerializeFMUstateTYPE     (fmi2Component, fmi2FMUstate, fmi2Byte[], size_t);\r
+   typedef fmi2Status fmi2DeSerializeFMUstateTYPE   (fmi2Component, const fmi2Byte[], size_t, fmi2FMUstate*); */\r
+   LOAD_DLL_FUNCTION_WITH_FLAG(fmi2GetFMUstate,fmi2_cs_canGetAndSetFMUstate);\r
+   LOAD_DLL_FUNCTION_WITH_FLAG(fmi2SetFMUstate,fmi2_cs_canGetAndSetFMUstate);\r
+   LOAD_DLL_FUNCTION_WITH_FLAG(fmi2FreeFMUstate,fmi2_cs_canGetAndSetFMUstate);\r
+   LOAD_DLL_FUNCTION_WITH_FLAG(fmi2SerializedFMUstateSize,fmi2_cs_canSerializeFMUstate);\r
+   LOAD_DLL_FUNCTION_WITH_FLAG(fmi2SerializeFMUstate,fmi2_cs_canSerializeFMUstate);\r
+   LOAD_DLL_FUNCTION_WITH_FLAG(fmi2DeSerializeFMUstate,fmi2_cs_canSerializeFMUstate);\r
+\r
+/* Getting directional derivatives */\r
+/*   typedef fmi2Status fmi2GetDirectionalDerivativeTYPE(fmi2Component, const fmi2ValueReference[], size_t,
+                                                                   const fmi2ValueReference[], size_t,
+                                                                   const fmi2Real[], fmi2Real[]);*/\r
+    LOAD_DLL_FUNCTION_WITH_FLAG(fmi2GetDirectionalDerivative,fmi2_cs_providesDirectionalDerivatives); \r
+
+/* Simulating the slave */\r
+/*   typedef fmi2Status fmi2SetRealInputDerivativesTYPE (fmi2Component, const fmi2ValueReference [], size_t, const fmi2Integer [], const fmi2Real []);\r
+   typedef fmi2Status fmi2GetRealOutputDerivativesTYPE(fmi2Component, const fmi2ValueReference [], size_t, const fmi2Integer [], fmi2Real []); */\r
+       LOAD_DLL_FUNCTION(fmi2SetRealInputDerivatives);
+       LOAD_DLL_FUNCTION(fmi2GetRealOutputDerivatives);
+\r
+/*   typedef fmi2Status fmi2DoStepTYPE     (fmi2Component, fmi2Real, fmi2Real, fmi2Boolean);\r
+   typedef fmi2Status fmi2CancelStepTYPE (fmi2Component); */\r
+       LOAD_DLL_FUNCTION(fmi2CancelStep);
+       LOAD_DLL_FUNCTION(fmi2DoStep);
+\r
+/* Inquire slave status */\r
+/*   typedef fmi2Status fmi2GetStatusTYPE       (fmi2Component, const fmi2StatusKind, fmi2Status* );\r
+   typedef fmi2Status fmi2GetRealStatusTYPE   (fmi2Component, const fmi2StatusKind, fmi2Real*   );\r
+   typedef fmi2Status fmi2GetIntegerStatusTYPE(fmi2Component, const fmi2StatusKind, fmi2Integer*);\r
+   typedef fmi2Status fmi2GetBooleanStatusTYPE(fmi2Component, const fmi2StatusKind, fmi2Boolean*);\r
+   typedef fmi2Status fmi2GetStringStatusTYPE (fmi2Component, const fmi2StatusKind, fmi2String* ); */\r
+       LOAD_DLL_FUNCTION(fmi2GetStatus);
+       LOAD_DLL_FUNCTION(fmi2GetRealStatus);
+       LOAD_DLL_FUNCTION(fmi2GetIntegerStatus);
+       LOAD_DLL_FUNCTION(fmi2GetBooleanStatus);
+       LOAD_DLL_FUNCTION(fmi2GetStringStatus);
+
+       return jm_status; 
+}
+
+/* Load FMI 2.0 Model Exchange functions */
+static jm_status_enu_t fmi2_capi_load_me_fcn(fmi2_capi_t* fmu, unsigned int capabilities[])
+{
+       jm_status_enu_t jm_status = jm_status_success;
+
+       jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Loading functions for the model exchange interface"); 
+
+       jm_status = fmi2_capi_load_common_fcn(fmu, capabilities);
+               /* Getting and setting the internal FMU state */\r
+/*   typedef fmi2Status fmi2GetFMUstateTYPE           (fmi2Component, fmi2FMUstate*);\r
+   typedef fmi2Status fmi2SetFMUstateTYPE           (fmi2Component, fmi2FMUstate);\r
+   typedef fmi2Status fmi2FreeFMUstateTYPE          (fmi2Component, fmi2FMUstate*);\r
+   typedef fmi2Status fmi2SerializedFMUstateSizeTYPE(fmi2Component, fmi2FMUstate, size_t*);\r
+   typedef fmi2Status fmi2SerializeFMUstateTYPE     (fmi2Component, fmi2FMUstate, fmi2Byte[], size_t);\r
+   typedef fmi2Status fmi2DeSerializeFMUstateTYPE   (fmi2Component, const fmi2Byte[], size_t, fmi2FMUstate*); */\r
+   LOAD_DLL_FUNCTION_WITH_FLAG(fmi2GetFMUstate,fmi2_me_canGetAndSetFMUstate);\r
+   LOAD_DLL_FUNCTION_WITH_FLAG(fmi2SetFMUstate,fmi2_me_canGetAndSetFMUstate);\r
+   LOAD_DLL_FUNCTION_WITH_FLAG(fmi2FreeFMUstate,fmi2_me_canGetAndSetFMUstate);\r
+   LOAD_DLL_FUNCTION_WITH_FLAG(fmi2SerializedFMUstateSize,fmi2_me_canSerializeFMUstate);\r
+   LOAD_DLL_FUNCTION_WITH_FLAG(fmi2SerializeFMUstate,fmi2_me_canSerializeFMUstate);\r
+   LOAD_DLL_FUNCTION_WITH_FLAG(fmi2DeSerializeFMUstate,fmi2_me_canSerializeFMUstate);\r
+\r
+/* Getting directional derivatives */\r
+/*   typedef fmi2Status fmi2GetDirectionalDerivativeTYPE(fmi2Component, const fmi2ValueReference[], size_t,
+                                                                   const fmi2ValueReference[], size_t,
+                                                                   const fmi2Real[], fmi2Real[]); */\r
+    LOAD_DLL_FUNCTION_WITH_FLAG(fmi2GetDirectionalDerivative,fmi2_me_providesDirectionalDerivatives); \r
+
+/* Enter and exit the different modes */
+/*   typedef fmi2Status fmi2EnterEventModeTYPE         (fmi2Component);
+   typedef fmi2Status fmi2NewDiscreteStatesTYPE      (fmi2Component, fmi2EventInfo*);
+   typedef fmi2Status fmi2EnterContinuousTimeModeTYPE(fmi2Component);
+   typedef fmi2Status fmi2CompletedIntegratorStepTYPE(fmi2Component, fmi2Boolean, fmi2Boolean*, fmi2Boolean*);*/
+       LOAD_DLL_FUNCTION(fmi2EnterEventMode);
+       LOAD_DLL_FUNCTION(fmi2NewDiscreteStates);
+       LOAD_DLL_FUNCTION(fmi2EnterContinuousTimeMode);
+       LOAD_DLL_FUNCTION(fmi2CompletedIntegratorStep);
+
+/* Providing independent variables and re-initialization of caching */\r
+   /*typedef fmi2Status fmi2SetTimeTYPE            (fmi2Component, fmi2Real);\r
+   typedef fmi2Status fmi2SetContinuousStatesTYPE(fmi2Component, const fmi2Real[], size_t);*/
+       LOAD_DLL_FUNCTION(fmi2SetTime);
+       LOAD_DLL_FUNCTION(fmi2SetContinuousStates);
+\r
+/* Evaluation of the model equations */
+
+/*\r
+   typedef fmi2Status fmi2GetDerivativesTYPE               (fmi2Component, fmi2Real[], size_t);\r
+   typedef fmi2Status fmi2GetEventIndicatorsTYPE           (fmi2Component, fmi2Real[], size_t);\r
+   typedef fmi2Status fmi2GetContinuousStatesTYPE          (fmi2Component, fmi2Real[], size_t);\r
+   typedef fmi2Status fmi2GetNominalsOfContinuousStatesTYPE(fmi2Component, fmi2Real[], size_t);*/
+       LOAD_DLL_FUNCTION(fmi2GetDerivatives);
+       LOAD_DLL_FUNCTION(fmi2GetEventIndicators);
+       LOAD_DLL_FUNCTION(fmi2GetContinuousStates);
+       LOAD_DLL_FUNCTION(fmi2GetNominalsOfContinuousStates);
+   
+       return jm_status; 
+}
+
+void fmi2_capi_destroy_dllfmu(fmi2_capi_t* fmu)
+{
+       if (fmu == NULL) {
+               return;
+       }
+       fmi2_capi_free_dll(fmu);
+       jm_log_debug(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Releasing allocated memory");
+       fmu->callbacks->free((void*)fmu->dllPath);
+       fmu->callbacks->free((void*)fmu->modelIdentifier);
+       fmu->callbacks->free((void*)fmu);
+}
+
+fmi2_capi_t* fmi2_capi_create_dllfmu(jm_callbacks* cb, const char* dllPath, const char* modelIdentifier, const fmi2_callback_functions_t* callBackFunctions, fmi2_fmu_kind_enu_t standard)
+{
+       fmi2_capi_t* fmu = NULL;
+
+       jm_log_debug(cb, FMI_CAPI_MODULE_NAME, "Initializing data structures for FMICAPI.");
+
+       /* Minor check for the callbacks */
+       if (cb == NULL) {
+               assert(0);
+               return NULL;
+       }
+
+       /* Allocate memory for the FMU instance */
+       fmu = (fmi2_capi_t*)cb->calloc(1, sizeof(fmi2_capi_t));
+       if (fmu == NULL) { /* Could not allocate memory for the FMU struct */
+               jm_log_fatal(cb, FMI_CAPI_MODULE_NAME, "Could not allocate memory for the FMU struct.");
+               return NULL;
+       }
+
+       /* Set the import package callback functions */
+       fmu->callbacks = cb;
+
+       /* Set the FMI callback functions */
+       fmu->callBackFunctions = *callBackFunctions;
+
+       /* Set FMI standard to load */
+       fmu->standard = standard;
+
+       /* Set all memory alloated pointers to NULL */
+       fmu->dllPath = NULL;
+       fmu->modelIdentifier = NULL;
+
+
+       /* Copy DLL path */
+       fmu->dllPath = (char*)cb->calloc(sizeof(char), strlen(dllPath) + 1);
+       if (fmu->dllPath == NULL) {
+               jm_log_fatal(cb, FMI_CAPI_MODULE_NAME, "Could not allocate memory for the DLL path string.");
+               fmi2_capi_destroy_dllfmu(fmu);
+               return NULL;
+       }
+       strcpy((char*)fmu->dllPath, dllPath);
+
+       /* Copy the modelIdentifier */
+       fmu->modelIdentifier = (char*)cb->calloc(sizeof(char), strlen(modelIdentifier) + 1);
+       if (fmu->modelIdentifier == NULL) {
+               jm_log_fatal(cb, FMI_CAPI_MODULE_NAME, "Could not allocate memory for the modelIdentifier string.");
+               fmi2_capi_destroy_dllfmu(fmu);
+               return NULL;
+       }
+       strcpy((char*)fmu->modelIdentifier, modelIdentifier);
+
+       jm_log_debug(cb, FMI_CAPI_MODULE_NAME, "Successfully initialized data structures for FMICAPI.");
+
+       /* Everything was successful */
+       return fmu;
+}
+
+jm_status_enu_t fmi2_capi_load_fcn(fmi2_capi_t* fmu, unsigned int capabilities[])
+{
+       assert(fmu);
+       /* Load ME functions */
+       if (fmu->standard == fmi2_fmu_kind_me) {
+               return fmi2_capi_load_me_fcn(fmu, capabilities);
+       /* Load CS functions */
+       } else if (fmu->standard == fmi2_fmu_kind_cs) {
+               return fmi2_capi_load_cs_fcn(fmu, capabilities);
+       } else {
+               jm_log_error(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Unexpected FMU kind in FMICAPI.");
+               return jm_status_error;
+       }
+}
+
+jm_status_enu_t fmi2_capi_load_dll(fmi2_capi_t* fmu)
+{
+       assert(fmu && fmu->dllPath);
+       fmu->dllHandle = jm_portability_load_dll_handle(fmu->dllPath); /* Load the shared library */
+       if (fmu->dllHandle == NULL) {
+               jm_log_fatal(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Could not load the DLL: %s", jm_portability_get_last_dll_error());
+               return jm_status_error;
+       } else {
+               jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Loaded FMU binary from %s", fmu->dllPath);
+               return jm_status_success;
+       }
+}
+
+void fmi2_capi_set_debug_mode(fmi2_capi_t* fmu, int mode) {
+       if(fmu)
+               fmu->debugMode = mode;
+}
+\r
+int fmi2_capi_get_debug_mode(fmi2_capi_t* fmu) {
+       if(fmu) return fmu->debugMode;
+       return 0;
+}
+
+fmi2_fmu_kind_enu_t fmi2_capi_get_fmu_kind(fmi2_capi_t* fmu) {
+       if(fmu) return fmu->standard;
+       return fmi2_fmu_kind_unknown;
+}
+
+jm_status_enu_t fmi2_capi_free_dll(fmi2_capi_t* fmu)
+{
+       if (fmu == NULL) {              
+               return jm_status_error; /* Return without writing any log message */
+       }
+
+       if (fmu->dllHandle) {
+               jm_status_enu_t status =
+                       (fmu->debugMode != 0) ?
+                /* When running valgrind this may be convenient to track mem leaks */ 
+                jm_status_success:
+                jm_portability_free_dll_handle(fmu->dllHandle);
+               fmu->dllHandle = 0;
+               if (status == jm_status_error) { /* Free the library handle */
+                       jm_log(fmu->callbacks, FMI_CAPI_MODULE_NAME, jm_log_level_error, "Could not free the DLL: %s", jm_portability_get_last_dll_error());
+                       return jm_status_error;
+               } else {
+                       jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Successfully unloaded FMU binary");
+                       return jm_status_success;
+               }
+       }
+       return jm_status_success;
+}
+
+/* Common FMI 2.0 functions */
+
+const char* fmi2_capi_get_version(fmi2_capi_t* fmu)
+{
+       assert(fmu);
+       return fmu->fmi2GetVersion();
+}
+\r
+const char* fmi2_capi_get_types_platform(fmi2_capi_t* fmu)\r
+{\r
+       assert(fmu);\r
+       jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Calling fmi2GetModelTypesPlatform");\r
+       return fmu->fmi2GetTypesPlatform();\r
+}\r
+
+fmi2_status_t fmi2_capi_set_debug_logging(fmi2_capi_t* fmu, fmi2_boolean_t loggingOn, size_t nCategories, fmi2_string_t categories[])
+{
+       return fmu->fmi2SetDebugLogging(fmu->c, loggingOn, nCategories, categories);
+}
+
+fmi2_component_t fmi2_capi_instantiate(fmi2_capi_t* fmu,
+  fmi2_string_t instanceName, fmi2_type_t fmuType, fmi2_string_t fmuGUID,
+  fmi2_string_t fmuResourceLocation, fmi2_boolean_t visible,
+  fmi2_boolean_t loggingOn)
+{
+    return fmu->c = fmu->fmi2Instantiate(instanceName, fmuType, fmuGUID,
+        fmuResourceLocation, &fmu->callBackFunctions, visible, loggingOn);
+}
+
+void fmi2_capi_free_instance(fmi2_capi_t* fmu)
+{
+    if(fmu != NULL && fmu->c != NULL) {
+        fmu->fmi2FreeInstance(fmu->c);
+        fmu->c = 0;
+    }
+}
+
+
+fmi2_status_t fmi2_capi_setup_experiment(fmi2_capi_t* fmu,
+    fmi2_boolean_t tolerance_defined, fmi2_real_t tolerance,
+    fmi2_real_t start_time, fmi2_boolean_t stop_time_defined,
+    fmi2_real_t stop_time)
+{
+    assert(fmu); assert(fmu->c);
+    jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Calling fmi2SetupExperiment");
+    return fmu->fmi2SetupExperiment(fmu->c, tolerance_defined, tolerance,
+                                   start_time, stop_time_defined, stop_time);
+}
+
+fmi2_status_t fmi2_capi_enter_initialization_mode(fmi2_capi_t* fmu)
+{
+    assert(fmu); assert(fmu->c);
+    jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Calling fmi2EnterInitializationMode");
+    return fmu->fmi2EnterInitializationMode(fmu->c);
+}
+
+fmi2_status_t fmi2_capi_exit_initialization_mode(fmi2_capi_t* fmu)
+{
+    assert(fmu); assert(fmu->c);
+    jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Calling fmi2ExitInitializationMode");
+    return fmu->fmi2ExitInitializationMode(fmu->c);
+}
+
+
+fmi2_status_t fmi2_capi_terminate(fmi2_capi_t* fmu)
+{
+       assert(fmu);
+       jm_log_debug(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Calling fmi2Terminate");
+       return fmu->fmi2Terminate(fmu->c);
+}
+
+fmi2_status_t fmi2_capi_reset(fmi2_capi_t* fmu)
+{
+       return fmu->fmi2Reset(fmu->c);
+}
+
+fmi2_status_t fmi2_capi_get_fmu_state           (fmi2_capi_t* fmu, fmi2_FMU_state_t* s) {\r
+       return fmu->fmi2GetFMUstate(fmu -> c,s);\r
+}\r
+fmi2_status_t fmi2_capi_set_fmu_state           (fmi2_capi_t* fmu, fmi2_FMU_state_t s){\r
+       return fmu->fmi2SetFMUstate(fmu -> c,s);\r
+}\r
+fmi2_status_t fmi2_capi_free_fmu_state          (fmi2_capi_t* fmu, fmi2_FMU_state_t* s){\r
+       return fmu->fmi2FreeFMUstate (fmu -> c,s);\r
+}\r
+fmi2_status_t fmi2_capi_serialized_fmu_state_size(fmi2_capi_t* fmu, fmi2_FMU_state_t s, size_t* sz){\r
+       return fmu->fmi2SerializedFMUstateSize(fmu -> c,s,sz);\r
+}\r
+fmi2_status_t fmi2_capi_serialize_fmu_state     (fmi2_capi_t* fmu, fmi2_FMU_state_t s , fmi2_byte_t data[], size_t sz){\r
+       return fmu->fmi2SerializeFMUstate(fmu -> c,s,data,sz);\r
+}\r
+fmi2_status_t fmi2_capi_de_serialize_fmu_state  (fmi2_capi_t* fmu, const fmi2_byte_t data[], size_t sz, fmi2_FMU_state_t* s){\r
+       return fmu->fmi2DeSerializeFMUstate (fmu -> c,data,sz,s);\r
+}\r
+\r
+fmi2_status_t fmi2_capi_get_directional_derivative(fmi2_capi_t* fmu, const fmi2_value_reference_t v_ref[], size_t nv,\r
+                                                                   const fmi2_value_reference_t z_ref[], size_t nz,\r
+                                                                   const fmi2_real_t dv[], fmi2_real_t dz[]){\r
+       return fmu->fmi2GetDirectionalDerivative(fmu -> c, z_ref, nz, v_ref, nv, dv, dz);\r
+}
+
+
+/* fmiSet* functions */
+#define FMISETX(FNAME1, FNAME2, FTYPE) \
+fmi2_status_t FNAME1(fmi2_capi_t* fmu, const fmi2_value_reference_t vr[], size_t nvr, const FTYPE value[])     \
+{ \
+       return fmu->FNAME2(fmu->c, vr, nvr, value); \
+}
+
+/* fmiGet* functions */
+#define FMIGETX(FNAME1, FNAME2, FTYPE) \
+fmi2_status_t FNAME1(fmi2_capi_t* fmu, const fmi2_value_reference_t vr[], size_t nvr, FTYPE value[]) \
+{ \
+       return fmu->FNAME2(fmu->c, vr, nvr, value); \
+}
+
+FMISETX(fmi2_capi_set_real,            fmi2SetReal,            fmi2_real_t)
+FMISETX(fmi2_capi_set_integer, fmi2SetInteger, fmi2_integer_t)
+FMISETX(fmi2_capi_set_boolean, fmi2SetBoolean, fmi2_boolean_t)
+FMISETX(fmi2_capi_set_string,  fmi2SetString,  fmi2_string_t)
+
+FMIGETX(fmi2_capi_get_real,    fmi2GetReal,            fmi2_real_t)
+FMIGETX(fmi2_capi_get_integer, fmi2GetInteger, fmi2_integer_t)
+FMIGETX(fmi2_capi_get_boolean, fmi2GetBoolean, fmi2_boolean_t)
+FMIGETX(fmi2_capi_get_string,  fmi2GetString,  fmi2_string_t)