Sorry I wasn't clear. The code is not the same. The old code relied on a `fmuTemplate.h`and a `fmuTemplate.c` that I am trying to port to Nim.
>From all the functions and data models that I have ported so far, in this >example the problem is on the `fmi2Instantiate` function. If I use the .c >version it works, while the .nim one fails. The C version is: fmi2Component fmi2Instantiate(fmi2String instanceName, fmi2Type fmuType, fmi2String fmuGUID, fmi2String fmuResourceLocation, const fmi2CallbackFunctions *functions, fmi2Boolean visible, fmi2Boolean loggingOn) { // ignoring arguments: fmuResourceLocation, visible ModelInstance *comp; if (!functions->logger) { return NULL; } if (!functions->allocateMemory || !functions->freeMemory) { functions->logger(functions->componentEnvironment, instanceName, fmi2Error, "error", "fmi2Instantiate: Missing callback function."); return NULL; } if (!instanceName || strlen(instanceName) == 0) { functions->logger(functions->componentEnvironment, "?", fmi2Error, "error", "fmi2Instantiate: Missing instance name."); return NULL; } if (!fmuGUID || strlen(fmuGUID) == 0) { functions->logger(functions->componentEnvironment, instanceName, fmi2Error, "error", "fmi2Instantiate: Missing GUID."); return NULL; } if (strcmp(fmuGUID, MODEL_GUID)) { functions->logger(functions->componentEnvironment, instanceName, fmi2Error, "error", "fmi2Instantiate: Wrong GUID %s. Expected %s.", fmuGUID, MODEL_GUID); return NULL; } comp = (ModelInstance *)functions->allocateMemory(1, sizeof(ModelInstance)); if (comp) { int i; comp->r = (fmi2Real *) functions->allocateMemory(NUMBER_OF_REALS, sizeof(fmi2Real)); comp->i = (fmi2Integer *)functions->allocateMemory(NUMBER_OF_INTEGERS, sizeof(fmi2Integer)); comp->b = (fmi2Boolean *)functions->allocateMemory(NUMBER_OF_BOOLEANS, sizeof(fmi2Boolean)); comp->s = (fmi2String *) functions->allocateMemory(NUMBER_OF_STRINGS, sizeof(fmi2String)); comp->isPositive = (fmi2Boolean *)functions->allocateMemory(NUMBER_OF_EVENT_INDICATORS, sizeof(fmi2Boolean)); comp->instanceName = (char *)functions->allocateMemory(1 + strlen(instanceName), sizeof(char)); comp->GUID = (char *)functions->allocateMemory(1 + strlen(fmuGUID), sizeof(char)); // set all categories to on or off. fmi2SetDebugLogging should be called to choose specific categories. for (i = 0; i < NUMBER_OF_CATEGORIES; i++) { comp->logCategories[i] = loggingOn; } } if (!comp || !comp->r || !comp->i || !comp->b || !comp->s || !comp->isPositive || !comp->instanceName || !comp->GUID) { functions->logger(functions->componentEnvironment, instanceName, fmi2Error, "error", "fmi2Instantiate: Out of memory."); return NULL; } comp->time = 0; // overwrite in fmi2SetupExperiment, fmi2SetTime strcpy((char *)comp->instanceName, (char *)instanceName); comp->type = fmuType; strcpy((char *)comp->GUID, (char *)fmuGUID); comp->functions = functions; comp->componentEnvironment = functions->componentEnvironment; comp->loggingOn = loggingOn; comp->state = modelInstantiated; setStartValues(comp); // to be implemented by the includer of this file comp->isDirtyValues = fmi2True; // because we just called setStartValues comp->isNewEventIteration = fmi2False; comp->eventInfo.newDiscreteStatesNeeded = fmi2False; comp->eventInfo.terminateSimulation = fmi2False; comp->eventInfo.nominalsOfContinuousStatesChanged = fmi2False; comp->eventInfo.valuesOfContinuousStatesChanged = fmi2False; comp->eventInfo.nextEventTimeDefined = fmi2False; comp->eventInfo.nextEventTime = 0; FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "fmi2Instantiate: GUID=%s", fmuGUID) return comp; } Run The Nim version is: proc fmi2Instantiate*( instanceName: fmi2String; fmuType: fmi2Type; fmuGUID: fmi2String; fmuResourceLocation: fmi2String; functions: fmi2CallbackFunctions; # <--- I suspect of this visible: fmi2Boolean; loggingOn: fmi2Boolean): ModelInstance = var comp:ModelInstance echo functions.logger.isNil echo functions.allocateMemory.isNil #echo functions.allocateMemory.isNil #[ # ignoring arguments: fmuResourceLocation, visible if f.logger.isNil: return nil if f.allocateMemory.isNil or f.freeMemory.isNil: f.logger( functions.componentEnvironment, instanceName, fmi2Error, "error".fmi2String, "fmi2Instantiate: Missing callback function.".fmi2String) return nil if instanceName.isNil or instanceName.len == 0: f.logger( functions.componentEnvironment, "?", fmi2Error, "error", "fmi2Instantiate: Missing instance name.") return nil if fmuGUID.isNil or fmuGUID.len == 0: f.logger( functions.componentEnvironment, instanceName, fmi2Error, "error", "fmi2Instantiate: Missing GUID.") return nil ]# #[ if not ($(fmuGUID) == MODEL_GUID): #strcmp(fmuGUID, MODEL_GUID)) { f.logger( functions.componentEnvironment, instanceName, fmi2Error, "error", fmt"fmi2Instantiate: Wrong GUID {$(fmuGUID)}. Expected {MODEL_GUID}.") return nil ]# #comp = (ModelInstance *)functions.allocateMemory(1, sizeof(ModelInstance)); # var comp = ModelInstance( time:0, # instanceName:instanceName, # `type`:fmuType, # GUID: fmuGUID ) comp.time = 0 comp.instanceName = instanceName comp.`type` = fmuType comp.GUID = fmuGUID comp.r = cast[typeof(comp.r)](realloc(comp.r, NUMBER_OF_REALS * sizeof(fmi2Real))) comp.i = cast[typeof(comp.i)](realloc(comp.i, NUMBER_OF_INTEGERS * sizeof(fmi2Integer))) comp.b = cast[typeof(comp.b)](realloc(comp.b, NUMBER_OF_BOOLEANS * sizeof(fmi2Boolean))) comp.s = cast[typeof(comp.s)](realloc(comp.s, NUMBER_OF_STRINGS * sizeof(fmi2String))) comp.isPositive = cast[typeof(comp.isPositive)](realloc(comp.isPositive, NUMBER_OF_EVENT_INDICATORS * sizeof(fmi2Boolean))) for i in 0 ..< NUMBER_OF_CATEGORIES: comp.logCategories[i] = loggingOn #[ if not comp.isNil: #[ comp.r = cast[typeof(comp.r)](realloc(comp.r, NUMBER_OF_REALS * sizeof(fmi2Real))) comp.i = cast[typeof(comp.i)](realloc(comp.i, NUMBER_OF_INTEGERS * sizeof(fmi2Integer))) comp.b = cast[typeof(comp.b)](realloc(comp.b, NUMBER_OF_BOOLEANS * sizeof(fmi2Boolean))) comp.s = cast[typeof(comp.s)](realloc(comp.s, NUMBER_OF_STRINGS * sizeof(fmi2String))) comp.isPositive = cast[typeof(comp.isPositive)](realloc(comp.isPositive, NUMBER_OF_EVENT_INDICATORS * sizeof(fmi2Boolean))) ]# #comp.instanceName = (char *)functions.allocateMemory(1 + strlen(instanceName), sizeof(char)); #comp.GUID = (char *)functions.allocateMemory(1 + strlen(fmuGUID), sizeof(char)); # set all categories to on or off. fmi2SetDebugLogging should be called to choose specific categories. for i in 0 ..< NUMBER_OF_CATEGORIES: comp.logCategories[i] = loggingOn ]# #[ if comp.isNil or comp.r.isNil or comp.i.isNil or comp.b.isNil or comp.s.isNil or comp.isPositive.isNil or comp.instanceName.isNil or comp.GUID.isNil: functions.logger(functions.componentEnvironment, instanceName, fmi2Error, "error", "fmi2Instantiate: Out of memory.") return nil ]# comp.functions = functions comp.componentEnvironment = functions.componentEnvironment comp.loggingOn = loggingOn comp.state = modelInstantiated # State changed setStartValues( comp ) # <------ to be implemented by the includer of this file comp.isDirtyValues = fmi2True # because we just called setStartValues comp.isNewEventIteration = fmi2False comp.eventInfo.newDiscreteStatesNeeded = fmi2False comp.eventInfo.terminateSimulation = fmi2False comp.eventInfo.nominalsOfContinuousStatesChanged = fmi2False comp.eventInfo.valuesOfContinuousStatesChanged = fmi2False comp.eventInfo.nextEventTimeDefined = fmi2False comp.eventInfo.nextEventTime = 0 filteredLog( comp, fmi2OK, LOG_FMI_CALL, fmt"fmi2Instantiate: GUID={$fmuGUID}") return comp Run I suspect about the `functions: fmi2CallbackFunctions; ` argument, because the following shows: `false` echo functions.logger.isNil echo functions.allocateMemory.isNil Run