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 1.0 Co-Simulation functions */ static jm_status_enu_t fmi1_capi_load_cs_fcn(fmi1_capi_t* fmu) { 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"); /* Workaround for Dymola 2012 and SimulationX 3.x */ if (fmi1_capi_get_fcn(fmu, "fmiGetTypesPlatform",(jm_dll_function_ptr*)&fmu->fmiGetTypesPlatform) == jm_status_error) { jm_log_warning(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Could not load the FMI function 'fmiGetTypesPlatform'. %s. Trying to load fmiGetModelTypesPlatform instead.", jm_portability_get_last_dll_error()); jm_status = jm_status_warning; if (fmi1_capi_get_fcn(fmu, "fmiGetModelTypesPlatform", (jm_dll_function_ptr*)&fmu->fmiGetTypesPlatform) == jm_status_error) { jm_log_error(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Could not load the FMI function 'fmiGetModelTypesPlatform'. %s", jm_portability_get_last_dll_error()); jm_status = jm_status_error; } } LOAD_DLL_FUNCTION(fmiInstantiateSlave); LOAD_DLL_FUNCTION(fmiInitializeSlave); LOAD_DLL_FUNCTION(fmiTerminateSlave); LOAD_DLL_FUNCTION(fmiResetSlave); LOAD_DLL_FUNCTION(fmiFreeSlaveInstance); LOAD_DLL_FUNCTION(fmiSetRealInputDerivatives); LOAD_DLL_FUNCTION(fmiGetRealOutputDerivatives); LOAD_DLL_FUNCTION(fmiCancelStep); LOAD_DLL_FUNCTION(fmiDoStep); LOAD_DLL_FUNCTION(fmiGetStatus); LOAD_DLL_FUNCTION(fmiGetRealStatus); LOAD_DLL_FUNCTION(fmiGetIntegerStatus); LOAD_DLL_FUNCTION(fmiGetBooleanStatus); LOAD_DLL_FUNCTION(fmiGetStringStatus); LOAD_DLL_FUNCTION(fmiGetVersion); LOAD_DLL_FUNCTION(fmiSetDebugLogging); LOAD_DLL_FUNCTION(fmiSetReal); LOAD_DLL_FUNCTION(fmiSetInteger); LOAD_DLL_FUNCTION(fmiSetBoolean); LOAD_DLL_FUNCTION(fmiSetString); LOAD_DLL_FUNCTION(fmiGetReal); LOAD_DLL_FUNCTION(fmiGetInteger); LOAD_DLL_FUNCTION(fmiGetBoolean); LOAD_DLL_FUNCTION(fmiGetString); return jm_status; }
/* Load and destroy functions */ jm_status_enu_t fmi2_import_create_dllfmu(fmi2_import_t* fmu, fmi2_fmu_kind_enu_t fmuKind, const fmi2_callback_functions_t* callBackFunctions) { char curDir[FILENAME_MAX + 2]; char* dllDirPath = 0; char* dllFileName = 0; const char* modelIdentifier; fmi2_callback_functions_t defaultCallbacks; if (fmu == NULL) { assert(0); return jm_status_error; } if(fmu -> capi) { if(fmi2_capi_get_fmu_kind(fmu -> capi) == fmuKind) { jm_log_warning(fmu->callbacks, module, "FMU binary is already loaded"); return jm_status_success; } else fmi2_import_destroy_dllfmu(fmu); } if(fmuKind == fmi2_fmu_kind_me) modelIdentifier = fmi2_import_get_model_identifier_ME(fmu); else if(fmuKind == fmi2_fmu_kind_cs) modelIdentifier = fmi2_import_get_model_identifier_CS(fmu); else { assert(0); return jm_status_error; } if (modelIdentifier == NULL) { jm_log_error(fmu->callbacks, module, "No model identifier given"); return jm_status_error; } if( jm_portability_get_current_working_directory(curDir, FILENAME_MAX+1) != jm_status_success) { jm_log_warning(fmu->callbacks, module, "Could not get current working directory (%s)", strerror(errno)); curDir[0] = 0; }; dllDirPath = fmi_construct_dll_dir_name(fmu->callbacks, fmu->dirPath); dllFileName = fmi_construct_dll_file_name(fmu->callbacks, dllDirPath, modelIdentifier); if (!dllDirPath ||!dllFileName) { fmu->callbacks->free(dllDirPath); return jm_status_error; } if(!callBackFunctions) { jm_callbacks* cb = fmu->callbacks; defaultCallbacks.allocateMemory = cb->calloc; defaultCallbacks.freeMemory = cb->free; defaultCallbacks.componentEnvironment = fmu; defaultCallbacks.logger = fmi2_log_forwarding; defaultCallbacks.stepFinished = 0; callBackFunctions = &defaultCallbacks; } if(jm_portability_set_current_working_directory(dllDirPath) != jm_status_success) { jm_log_fatal(fmu->callbacks, module, "Could not change to the DLL directory %s", dllDirPath); if(ENOENT == errno) jm_log_fatal(fmu->callbacks, module, "No binary for this platform?"); else jm_log_fatal(fmu->callbacks, module, "System error: %s", strerror(errno)); } else { /* Allocate memory for the C-API struct */ fmu -> capi = fmi2_capi_create_dllfmu(fmu->callbacks, dllFileName, modelIdentifier, callBackFunctions, fmuKind); } /* Load the DLL handle */ if (fmu -> capi) { jm_log_info(fmu->callbacks, module, "Loading '" FMI_PLATFORM "' binary with '%s' platform types", fmi2_get_types_platform() ); if(fmi2_capi_load_dll(fmu -> capi) == jm_status_error) { fmi2_capi_destroy_dllfmu(fmu -> capi); fmu -> capi = NULL; } } if(curDir[0] && (jm_portability_set_current_working_directory(curDir) != jm_status_success)) { jm_log_error(fmu->callbacks, module, "Could not restore current working directory (%s)", strerror(errno)); } fmu->callbacks->free((jm_voidp)dllDirPath); fmu->callbacks->free((jm_voidp)dllFileName); if (fmu -> capi == NULL) { return jm_status_error; } /* Load the DLL functions */ if (fmi2_capi_load_fcn(fmu -> capi, fmi2_xml_get_capabilities(fmu->md)) == jm_status_error) { fmi2_capi_free_dll(fmu -> capi); fmi2_capi_destroy_dllfmu(fmu -> capi); fmu -> capi = NULL; return jm_status_error; } jm_log_verbose(fmu->callbacks, module, "Successfully loaded all the interface functions"); return jm_status_success; }