int fmi2_test(fmi_import_context_t* context, const char* dirPath) { fmi2_callback_functions_t callBackFunctions; const char* modelIdentifier; const char* modelName; const char* GUID; jm_status_enu_t status; fmi2_import_t* fmu; fmi2_fmu_kind_enu_t fmukind; callBackFunctions.logger = fmi2logger; callBackFunctions.allocateMemory = calloc; callBackFunctions.freeMemory = free; callBackFunctions.stepFinished = stepFinished; callBackFunctions.componentEnvironment = 0; fmu = fmi2_import_parse_xml(context, dirPath, 0); if(!fmu) { printf("Error parsing XML, exiting\n"); return (CTEST_RETURN_FAIL); } modelName = fmi2_import_get_model_name(fmu); GUID = fmi2_import_get_GUID(fmu); printf("Model name: %s\n", modelName); if(fmi2_import_get_fmu_kind(fmu) != fmi2_fmu_kind_cs) { modelIdentifier = fmi2_import_get_model_identifier_ME(fmu); printf("Model identifier for ME: %s\n", modelIdentifier); fmukind = fmi2_fmu_kind_me; } else if(fmi2_import_get_fmu_kind(fmu) != fmi2_fmu_kind_me) { modelIdentifier = fmi2_import_get_model_identifier_CS(fmu); printf("Model identifier for CS: %s\n", modelIdentifier); fmukind = fmi2_fmu_kind_cs; } else { printf("Unxepected FMU kind, exiting\n"); return (CTEST_RETURN_FAIL); } printf("Model GUID: %s\n", GUID); status = fmi2_import_create_dllfmu(fmu, fmukind, &callBackFunctions); if (status == jm_status_error) { printf("Could not create the DLL loading mechanism(C-API).\n"); return(CTEST_RETURN_FAIL); } printf("Version returned from FMU: %s\n", fmi2_import_get_version(fmu)); fmi2_import_destroy_dllfmu(fmu); fmi2_import_free(fmu); return (CTEST_RETURN_SUCCESS); }
void FMI2ModelExchangeDestructor_OMC(void* in_fmi2me) { FMI2ModelExchange* FMI2ME = (FMI2ModelExchange*)in_fmi2me; fmi2_import_terminate(FMI2ME->FMIImportInstance); fmi2_import_free_instance(FMI2ME->FMIImportInstance); fmi2_import_destroy_dllfmu(FMI2ME->FMIImportInstance); fmi2_import_free(FMI2ME->FMIImportInstance); fmi_import_free_context(FMI2ME->FMIImportContext); free(FMI2ME->FMIWorkingDirectory); free(FMI2ME->FMIInstanceName); free(FMI2ME->FMIEventInfo); }
void fmi2_import_free(fmi2_import_t* fmu) { jm_callbacks* cb = fmu->callbacks; if(!fmu) return; jm_log_verbose( fmu->callbacks, "FMILIB", "Releasing allocated library resources"); fmi2_import_destroy_dllfmu(fmu); fmi2_xml_free_model_description(fmu->md); jm_vector_free_data(char)(&fmu->logMessageBufferCoded); jm_vector_free_data(char)(&fmu->logMessageBufferExpanded); cb->free(fmu->resourceLocation); cb->free(fmu->dirPath); cb->free(fmu); }
int main(int argc, char *argv[]) { fmi2_callback_functions_t callBackFunctions; const char* FMUPath; const char* tmpPath; jm_callbacks callbacks; fmi_import_context_t* context; fmi_version_enu_t version; jm_status_enu_t status; fmi2_import_t* fmu; if(argc < 3) { printf("Usage: %s <fmu_file> <temporary_dir>\n", argv[0]); do_exit(CTEST_RETURN_FAIL); } FMUPath = argv[1]; tmpPath = argv[2]; callbacks.malloc = malloc; callbacks.calloc = calloc; callbacks.realloc = realloc; callbacks.free = free; callbacks.logger = jm_default_logger; callbacks.log_level = jm_log_level_debug; callbacks.context = 0; #ifdef FMILIB_GENERATE_BUILD_STAMP printf("Library build stamp:\n%s\n", fmilib_get_build_stamp()); #endif context = fmi_import_allocate_context(&callbacks); version = fmi_import_get_fmi_version(context, FMUPath, tmpPath); if(version != fmi_version_2_0_enu) { printf("Only version 2.0 is supported by this code\n"); do_exit(CTEST_RETURN_FAIL); } fmu = fmi2_import_parse_xml(context, tmpPath,0); if(!fmu) { printf("Error parsing XML, exiting\n"); do_exit(CTEST_RETURN_FAIL); } if(fmi2_import_get_fmu_kind(fmu) == fmi2_fmu_kind_cs) { printf("Only ME 2.0 is supported by this code\n"); do_exit(CTEST_RETURN_FAIL); } callBackFunctions.logger = fmi2_log_forwarding; callBackFunctions.allocateMemory = calloc; callBackFunctions.freeMemory = free; callBackFunctions.componentEnvironment = fmu; status = fmi2_import_create_dllfmu(fmu, fmi2_fmu_kind_me, &callBackFunctions); if (status == jm_status_error) { printf("Could not create the DLL loading mechanism(C-API test).\n"); do_exit(CTEST_RETURN_FAIL); } test_simulate_me(fmu); fmi2_import_destroy_dllfmu(fmu); fmi2_import_free(fmu); fmi_import_free_context(context); printf("Everything seems to be OK since you got this far=)!\n"); do_exit(CTEST_RETURN_SUCCESS); return 0; }
/* 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; }