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;
}
Exemple #2
0
char* jm_create_URL_from_abs_path(jm_callbacks* cb, const char* path) {
	/* worst case: all symbols are 4-byte UTF-8 and need to be %-encoded */
#define MAX_URL_LENGTH  (FILENAME_MAX * 4 * 3 + 7)
	char buffer[MAX_URL_LENGTH];
	char* url;
	size_t urllen;
	if(!cb) {
		cb = jm_get_default_callbacks();
	}

#if defined(_WIN32) || defined(WIN32)
	{
		DWORD pathLen = MAX_URL_LENGTH;
		HRESULT code = UrlCreateFromPathA(
			path,
			buffer,
			&pathLen,
			0);
		if( (code != S_FALSE) && (code != S_OK)) {
			jm_log_fatal(cb, module,"Could not constuct file URL from path %s", path);
			return 0;
		}
		urllen = pathLen;
	}
#else
	{
		size_t i, len = strlen(path);
		char *curBuf = buffer + 7;
		unsigned char ch;
		strcpy(buffer, "file://");
		for( i = 0; i < len; i++) {
			ch = (unsigned char)path[i];
			if( (ch == '/') || ((ch >= 'A') && (ch <= 'Z')) 
				|| ((ch >= 'a') && (ch <= 'z'))
				|| (ch == '-') || (ch == '_') || (ch == '.') ||(ch == '~')) {
					*curBuf = ch;
					curBuf++;
					continue;
			}
			sprintf(curBuf, "%%%2X", (int)ch);/*safe*/
			curBuf+=3;
		}
		*curBuf = 0;
		urllen = curBuf - buffer;
	}
#endif
	url = (char*)cb->malloc(urllen+1);
	if(!url) {
		jm_log_fatal(cb, module,"Could not allocate memory");
		return 0;
	}
	strcpy(url, buffer);
	return url;
}
Exemple #3
0
char* jm_mk_temp_dir(jm_callbacks* cb, const char* systemTempDir, const char* tempPrefix)
{
	size_t len;

	char tmpDir[FILENAME_MAX + 2];
	char* tmpPath;

	if(!cb) {
		cb = jm_get_default_callbacks();
	}
	if(!systemTempDir) {
		systemTempDir = jm_get_system_temp_dir();
		if(!systemTempDir) systemTempDir = "./";
	}
	if(!tempPrefix) {
		tempPrefix = "jm";
	}
	len = strlen(systemTempDir);

	if(!jm_get_dir_abspath(cb, systemTempDir, tmpDir, FILENAME_MAX + 2)) {
		return 0;
	}

	len = strlen(tmpDir);
	if(tmpDir[len-1] != FMI_FILE_SEP[0]) {
		tmpDir[len] = FMI_FILE_SEP[0]; 
		tmpDir[len+1] = 0;
		len++;
	}
	len += strlen(tempPrefix) + 6;
	if(len + 16 > FILENAME_MAX) {
		jm_log_fatal(cb,module, "Canonical name for the temporary files directory is too long (system limit for path length is %d)", FILENAME_MAX);
		return 0;
	}
	tmpPath = (char*)cb->malloc(len + 7);
	if(!tmpPath) {
		jm_log_fatal(cb, module,"Could not allocate memory");
		return 0;
	}
	sprintf(tmpPath,"%s%sXXXXXX",tmpDir,tempPrefix);/*safe*/

	if(!jm_mktemp(tmpPath)) {
		jm_log_fatal(cb, module,"Could not create a unique temporary directory name");
		cb->free(tmpPath);
		return 0;
	}
	if(jm_mkdir(cb,tmpPath) != jm_status_success) {
		cb->free(tmpPath);
		return 0;
	}
	return tmpPath;
}
Exemple #4
0
/*#include "fmi1_import_vendor_annotations_impl.h"
#include "fmi1_import_parser.h"
*/
fmi1_import_t* fmi1_import_allocate(jm_callbacks* cb) {
	fmi1_import_t* fmu = (fmi1_import_t*)cb->calloc(1, sizeof(fmi1_import_t));
    
	if(!fmu || (jm_vector_init(char)(&fmu->logMessageBufferCoded,JM_MAX_ERROR_MESSAGE_SIZE,cb) < JM_MAX_ERROR_MESSAGE_SIZE)) {
		jm_log_fatal(cb, module, "Could not allocate memory");
        if(fmu) cb->free(fmu);
		return 0;
	}
    

	fmu->dirPath = 0;
	fmu->location = 0;
	fmu->callbacks = cb;
	fmu->capi = 0;
	fmu->md = fmi1_xml_allocate_model_description(cb);
	fmu->registerGlobally = 0;
	jm_vector_init(char)(&fmu->logMessageBufferExpanded,0,cb);

	if(!fmu->md) {
		cb->free(fmu);
		return 0;
	}

	return fmu;
}
Exemple #5
0
fmi2_import_t* fmi2_import_parse_xml( fmi_import_context_t* context, const char* dirPath, fmi2_xml_callbacks_t* xml_callbacks) {
	char* xmlPath;
	char absPath[FILENAME_MAX + 2];
	fmi2_import_t* fmu = 0;

	if(strlen(dirPath) + 20 > FILENAME_MAX) {
		jm_log_fatal(context->callbacks, module, "Directory path for FMU is too long");
		return 0;
	}

	xmlPath =  fmi_import_get_model_description_path(dirPath, context->callbacks);
	fmu = fmi2_import_allocate(context->callbacks);

	if(!fmu) {
		context->callbacks->free(xmlPath);
		return 0;
	}

	if(jm_get_dir_abspath(context->callbacks, dirPath, absPath, FILENAME_MAX + 2)) {
		size_t len = strlen(absPath);
		strcpy(absPath + len, FMI_FILE_SEP "resources");
		fmu->resourceLocation = fmi_import_create_URL_from_abs_path(context->callbacks, absPath);
	}
	fmu->dirPath =  context->callbacks->malloc(strlen(dirPath) + 1);
	if (!fmu->dirPath ||  !fmu->resourceLocation) {
		jm_log_fatal( context->callbacks, "FMILIB", "Could not allocated memory");
		fmi2_import_free(fmu);
		context->callbacks->free(xmlPath);
		return 0;
	}
	strcpy(fmu->dirPath, dirPath);

	jm_log_verbose( context->callbacks, "FMILIB", "Parsing model description XML");

	if(fmi2_xml_parse_model_description( fmu->md, xmlPath, xml_callbacks)) {
		fmi2_import_free(fmu);
		fmu = 0;
	}
	context->callbacks->free(xmlPath);

	if(fmu)
		jm_log_verbose( context->callbacks, "FMILIB", "Parsing finished successfully");

	return fmu;
}
Exemple #6
0
jm_status_enu_t jm_mkdir(jm_callbacks* cb, const char* dir) {
	if(!cb) {
		cb = jm_get_default_callbacks();
	}
	if(MKDIR(dir)) {
		jm_log_fatal(cb,module,"Could not create directory %s", dir);
		return jm_status_error;
	}
	else
		return jm_status_success;
}
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 FMU binary: %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;
	}
}
fmi_version_enu_t fmi_import_get_fmi_version( fmi_import_context_t* c, const char* fileName, const char* dirName) {
	fmi_version_enu_t ret = fmi_version_unknown_enu;
	jm_status_enu_t status;
	char* mdpath;
	jm_log_verbose(c->callbacks, MODULE, "Detecting FMI standard version");
	if(!fileName || !*fileName) {
		jm_log_fatal(c->callbacks, MODULE, "No FMU filename specified");
		return fmi_version_unknown_enu;
	}
	if(!dirName || !*dirName) {
		jm_log_fatal(c->callbacks, MODULE, "No temporary directory name specified");
		return fmi_version_unknown_enu;
	}
	status = fmi_zip_unzip(fileName, dirName, c->callbacks);
	if(status == jm_status_error) return fmi_version_unknown_enu;
	mdpath = fmi_import_get_model_description_path(dirName, c->callbacks);
	ret = fmi_xml_get_fmi_version(c, mdpath);
	jm_log_info(c->callbacks, MODULE, "XML specifies FMI standard version %s", fmi_version_to_string(ret));
	c->callbacks->free(mdpath);
	return ret;
}
Exemple #9
0
/* Loading shared library functions */
static jm_status_enu_t fmi1_capi_get_fcn(fmi1_capi_t* fmu, const char* function_name, jm_dll_function_ptr* dll_function_ptrptr)
{
	char fname[FUNCTION_NAME_LENGTH_MAX];
	
	if (strlen(fmu->modelIdentifier) + strlen(function_name) + 2 > FUNCTION_NAME_LENGTH_MAX) {
		jm_log_fatal(fmu->callbacks, FMI_CAPI_MODULE_NAME, "DLL function name is too long. Max name length is set to %s.", STRINGIFY(FUNCTION_NAME_LENGTH_MAX));
		return jm_status_error;
	}	

	sprintf(fname,"%s_%s",fmu->modelIdentifier, function_name);

	return jm_portability_load_dll_function(fmu->dllHandle, fname, dll_function_ptrptr);
}
Exemple #10
0
char* jm_get_dir_abspath(jm_callbacks* cb, const char* dir, char* outPath, size_t len) {
	char curDir[FILENAME_MAX + 2];

	if(!cb) {
		cb = jm_get_default_callbacks();
	}
	if( jm_portability_get_current_working_directory(curDir, FILENAME_MAX+1) != jm_status_success) {
		jm_log_fatal(cb,module, "Could not get current working directory (%s)", strerror(errno));
		return 0;
	};

	if(jm_portability_set_current_working_directory(dir) != jm_status_success) {
		jm_log_fatal(cb,module, "Could not change to the directory %s", dir);
		jm_portability_set_current_working_directory(curDir);
		return 0;
	};
	if( jm_portability_get_current_working_directory(outPath, len) != jm_status_success) {
		jm_log_fatal(cb,module, "Could not get absolute path for the directory (%s)", strerror(errno));
		jm_portability_set_current_working_directory(curDir);
		return 0;
	};
	jm_portability_set_current_working_directory(curDir);
	return outPath;
}
char* fmi_construct_dll_file_name(jm_callbacks* callbacks, const char* dll_dir_name, const char* model_identifier) {
	char* fname;
	size_t len;
	assert(callbacks && model_identifier);
	len = 
		strlen(dll_dir_name) +
		strlen(model_identifier) 
		+ strlen(FMI_DLL_EXT) + 1;
	fname = (char*)callbacks->malloc(len);
	if (fname == NULL) {
		jm_log_fatal(callbacks, "FMIUT", "Failed to allocate memory.");
		return NULL;
	}
	sprintf(fname, "%s%s%s", dll_dir_name, model_identifier, FMI_DLL_EXT);/*safe */

	return fname;
}
Exemple #12
0
fmi1_import_t* fmi1_import_parse_xml( fmi_import_context_t* context, const char* dirPath) {
	char* xmlPath; 
	char absPath[FILENAME_MAX + 2];
	jm_callbacks* cb;
	fmi1_import_t* fmu;

	if(!context) return 0;

	cb = context->callbacks; 
	
	xmlPath =  fmi_import_get_model_description_path(dirPath, context->callbacks);

	fmu = fmi1_import_allocate(context->callbacks);

	if(!fmu) {
		context->callbacks->free(xmlPath);
		return 0;
	}
	
	jm_log_verbose( cb, "FMILIB", "Parsing model description XML");

	if(fmi1_xml_parse_model_description( fmu->md, xmlPath)) {
		fmi1_import_free(fmu);
		cb->free(xmlPath);
		return 0;
	}
	cb->free(xmlPath);
	
	fmu->dirPath =  (char*)cb->calloc(strlen(dirPath) + 1, sizeof(char));

	if(jm_get_dir_abspath(cb, dirPath, absPath, FILENAME_MAX + 2)) {
		fmu->location = fmi_import_create_URL_from_abs_path(cb, absPath);
	}
	
	if ((fmu->dirPath == NULL) || (fmu->location == 0)){
		jm_log_fatal( cb, "FMILIB", "Could not allocated memory");
		fmi1_import_free(fmu);
		cb->free(xmlPath);
		return 0;
	}
	strcpy(fmu->dirPath, dirPath);

	jm_log_verbose( cb, "FMILIB", "Parsing finished successfully");

	return fmu;
}
char* fmi_construct_dll_dir_name(jm_callbacks* callbacks, const char* fmu_unzipped_path) {
	char* dir_path;
	size_t len;

	assert( fmu_unzipped_path && callbacks);

	len = 
		strlen(fmu_unzipped_path) + strlen(FMI_FILE_SEP)
		+ strlen(FMI_BINARIES) + strlen(FMI_FILE_SEP) 
		+ strlen(FMI_PLATFORM) + strlen(FMI_FILE_SEP) + 1;

	dir_path = (char*)callbacks->malloc(len);
	if (dir_path == NULL) {
		jm_log_fatal(callbacks, "FMIUT", "Failed to allocate memory.");
		return NULL;
	}

	sprintf(dir_path, "%s%s%s%s%s%s", fmu_unzipped_path, FMI_FILE_SEP, FMI_BINARIES, FMI_FILE_SEP, FMI_PLATFORM, FMI_FILE_SEP);/*safe */

	return dir_path;
}
fmi1_xml_model_description_t * fmi1_xml_allocate_model_description( jm_callbacks* callbacks) {
    jm_callbacks* cb;
    fmi1_xml_model_description_t* md;

    if(callbacks) {
        cb = callbacks;
    }
    else {
        cb = jm_get_default_callbacks();
    }
    md = (fmi1_xml_model_description_t*)cb->malloc(sizeof(fmi1_xml_model_description_t));
    if(!md) {
		jm_log_fatal(cb, module, "Could not allocate memory");
		return 0;
	}

    md->callbacks = cb;

    md->status = fmi1_xml_model_description_enu_empty;

    jm_vector_init(char)( & md->fmi1_xml_standard_version, 0,cb);
    jm_vector_init(char)(&md->modelName, 0,cb);
    jm_vector_init(char)(&md->modelIdentifier, 0,cb);
    jm_vector_init(char)(&md->GUID, 0,cb);
    jm_vector_init(char)(&md->description, 0,cb);
    jm_vector_init(char)(&md->author, 0,cb);
    jm_vector_init(char)(&md->version, 0,cb);
    jm_vector_init(char)(&md->generationTool, 0,cb);
    jm_vector_init(char)(&md->generationDateAndTime, 0,cb);


    md->namingConvension = fmi1_naming_enu_flat;
    md->numberOfContinuousStates = 0;
    md->numberOfEventIndicators = 0;

    md->defaultExperimentStartTime = 0;

    md->defaultExperimentStopTime = 1.0;

    md->defaultExperimentTolerance = FMI1_DEFAULT_EXPERIMENT_TOLERANCE;

    jm_vector_init(jm_voidp)(&md->vendorList, 0, cb);

    jm_vector_init(jm_named_ptr)(&md->unitDefinitions, 0, cb);
    jm_vector_init(jm_named_ptr)(&md->displayUnitDefinitions, 0, cb);

    fmi1_xml_init_type_definitions(&md->typeDefinitions, cb);

    jm_vector_init(jm_named_ptr)(&md->variablesByName, 0, cb);

	md->variablesOrigOrder = 0;

	md->variablesByVR = 0;

	md->inputVariables = 0;

	md->outputVariables = 0;

    jm_vector_init(jm_string)(&md->descriptions, 0, cb);

    md->fmuKind = fmi1_fmu_kind_enu_me;

    fmi1_xml_init_capabilities(&md->capabilities);

    jm_vector_init(jm_string)(&md->additionalModels, 0, cb);

    jm_vector_init(char)(&md->entryPoint, 0,cb);
    jm_vector_init(char)(&md->mimeType, 0,cb);

    return md;
}
Exemple #15
0
jm_status_enu_t fmi1_cs_simulate(fmu_check_data_t* cdata)
{	
	fmi1_status_t fmistatus;
	jm_status_enu_t jmstatus = jm_status_success;
	jm_callbacks* cb = &cdata->callbacks;

	fmi1_import_t* fmu = cdata->fmu1;
	fmi1_string_t fmuGUID = fmi1_import_get_GUID(fmu);
	fmi1_string_t mimeType;
	fmi1_real_t timeout = 0.0;
	fmi1_boolean_t visible = fmi1_false;
	fmi1_boolean_t interactive = fmi1_false;

	fmi1_real_t tstart = fmi1_import_get_default_experiment_start(fmu);
	fmi1_real_t tcur = tstart;
	fmi1_real_t hstep;
	fmi1_real_t tend = fmi1_import_get_default_experiment_stop(fmu);
	fmi1_boolean_t StopTimeDefined = fmi1_true;

	mimeType = fmi1_import_get_mime_type(fmu);
	if(	(cdata->fmu1_kind == fmi1_fmu_kind_enu_cs_standalone) 
		|| !mimeType || !mimeType[0])
	{
		mimeType = "application/x-fmu-sharedlibrary";
	}
	else {
		if(	strcmp(mimeType, "application/x-fmu-sharedlibrary") != 0 )
		{
			jm_log_info(cb, fmu_checker_module,"The FMU requests simulator with MIME type '%s'.", mimeType);
			printf("\nPlease, start a simulator program for MIME type '%s'\nPress enter to continue.\n", mimeType);
			getchar();
		}
	}
	if(cdata->stopTime > 0) {
		tend = cdata->stopTime;
	}
	if(cdata->stepSize > 0) {
		hstep = cdata->stepSize;
	}
	else {
		hstep = (tend - tstart) / cdata->numSteps;
	}

	cdata->instanceName = "Test FMI 1.0 CS";
	jm_log_verbose(cb, fmu_checker_module, "Checker will instantiate the slave with \n"
		"\tFMU location ='%s'\n\tMIME type = '%s'", cdata->fmuLocation, mimeType);
	jmstatus = fmi1_import_instantiate_slave(fmu, cdata->instanceName, cdata->fmuLocation, mimeType, timeout, visible, interactive);
	if (jmstatus == jm_status_error) {
		jm_log_fatal(cb, fmu_checker_module, "Could not instantiate the model");
		return jm_status_error;
	}

	fmistatus = fmi1_import_initialize_slave(fmu, tstart, StopTimeDefined, tend);
	if((fmistatus == fmi1_status_ok) || (fmistatus == fmi1_status_warning)) {
		jm_log_info(cb, fmu_checker_module, "Initialized FMU for simulation starting at time %g", tstart);
		fmistatus = fmi1_status_ok;
	}
	else {
			jm_log_fatal(cb, fmu_checker_module, "Failed to initialize FMU for simulation (FMU status: %s)", fmi1_status_to_string(fmistatus));
			jmstatus = jm_status_error;
	}

	if(jmstatus != jm_status_error) {
		jm_log_verbose(cb, fmu_checker_module, "Writing simulation output for start time");
		if(fmi1_write_csv_data(cdata, tstart) != jm_status_success){
			jmstatus = jm_status_error;
		}
	}
	while ((tcur < tend) && (jmstatus != jm_status_error)) {
		fmi1_boolean_t newStep = fmi1_true;
		fmi1_real_t tnext = tcur + hstep;
		if(tnext > tend - 1e-3*hstep) { /* last step should be on tend */
			hstep = tend - tcur;
			tnext = tend;
		}

		jm_log_verbose(cb, fmu_checker_module, "Simulation step from time: %g until: %g", tcur, tnext);

		fmistatus = fmi1_import_do_step(fmu, tcur, hstep, newStep);

		tcur = tnext;

		if(fmi1_write_csv_data(cdata, tcur) != jm_status_success){
			jmstatus = jm_status_error;
		}

		if((fmistatus == fmi1_status_ok) || (fmistatus == fmi1_status_warning)) {
			fmistatus = fmi1_status_ok;
		}
		else 
			jmstatus = jm_status_error;
	}

	if((fmistatus != fmi1_status_ok) && (fmistatus != fmi1_status_warning)) {
		jm_log_fatal(cb, fmu_checker_module, "Simulation loop terminated  at time %g since FMU returned status: %s", tcur, fmi1_status_to_string(fmistatus));
		jmstatus = jm_status_error;
	}
	else if(jmstatus != jm_status_error) {
 		 jm_log_info(cb, fmu_checker_module, "Simulation finished successfully at time %g", tcur);
	}

	fmistatus = fmi1_import_terminate_slave(fmu);

	if(  fmistatus != fmi1_status_ok) {
		 jm_log_error(cb, fmu_checker_module, "fmiTerminateSlave returned status: %s", fmi1_status_to_string(fmistatus));
	}

	fmi1_import_free_slave_instance(fmu);

	return jmstatus;
}
/* 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;
}