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

Reply via email to