Opened 13 years ago

Closed 11 years ago

#1732 closed defect (invalid)

Simulation errors with external functions which return record objects

Reported by: e.da-silva Owned by: Martin Sjölund
Priority: high Milestone:
Component: Code Generation Version:
Keywords: Cc: e.da-silva

Description

Hi,

It is not possible to use any external Modelica function which returns a record object.

I built a simple external function that add two complex numbers. The real and imaginary components of the number are passed as argument of the exernal function. The result is stored in the content of two double variables passed by address:


#ifndef _RECORDFKT_H
#define _RECORDFKT_H

#ifdef RECORDEXT_dll

#define RECORDEXT_Export declspec(dllexport)

#else

#ifdef cplusplus

#define RECORDEXT_Export declspec(dllimport)

#else

#define RECORDEXT_Export

#endif

#endif

#ifdef cplusplus

#define EXTERN extern "C"

#else

#define EXTERN extern

#endif

EXTERN RECORDEXT_Export int addLibComplexNum(double realX1, double imgX1,double realX2, double imgX2,double* realY,double* imgY);

#endif _RECORDFKT_H


#include "recordFkt.h"

int addLibComplexNum(double realX1, double imgX1,double realX2, double imgX2,double* realY,double* imgY)
{

*realY = realX1 + realX2;
*imgY = imgX1 + imgX2;
return 1;

}


The Modelica interface, a package, contains a function, a record and a model tester:


package ExpRecordPkg

function addLibComplexNum "function for external test"

input ExpRecordPkg.ComplexRec x1;
input ExpRecordPkg.ComplexRec x2;
output ExpRecordPkg.ComplexRec y = ExpRecordPkg.ComplexRec(0,0);

external "C" addLibComplexNum(x1.realComp,x1.imagComp,x2.realComp,x2.imagComp,y.realComp,y.imagComp) annotation(Library="recordExterFkt");

end addLibComplexNum;

model RecordExtFktTester

parameter ExpRecordPkg.ComplexRec x1 = ExpRecordPkg.ComplexRec(2,2);
parameter ExpRecordPkg.ComplexRec x2 = ExpRecordPkg.ComplexRec(2,1);
ExpRecordPkg.ComplexRec y;

equation

y = ExpRecordPkg.addLibComplexNum(x1,x2);

end RecordExtFktTester;

record ComplexRec

Real realComp;
Real imagComp;

end ComplexRec;
annotation (uses(Modelica(version="3.2")));

end ExpRecordPkg;


In OM 1.8.1 rev 11758, I get the following error message in OMShell:

simulate(ExpRecordPkg.RecordExtFktTester)

record SimulationResult

resultFile = "",
simulationOptions = "startTime = 0.0, stopTime = 1.0, numberOfIntervals = 500, tolerance = 1e-006, method = 'dassl', fileNamePrefix = 'ExpRecordPkg.RecordExtFktTester', storeInTemp = false, noClean = false, options = , outputFormat = 'mat', variableFilter = '.*', measureTime = false, cflags = , simflags = ",
messages = "Simulation failed for model: ExpRecordPkg.RecordExtFktTester

[C:/Users/erick/Desktop/TISC_OM_report/ProblemTester/recordExterFkt/modelica/ExpRecordPkg.mo:5:5-5:37:writable] Warning: Unused input variable x1 in function .ExpRecordPkg.addLibComplexNum.
[C:/Users/erick/Desktop/TISC_OM_report/ProblemTester/recordExterFkt/modelica/ExpRecordPkg.mo:6:5-6:37:writable] Warning: Unused input variable x2 in function .ExpRecordPkg.addLibComplexNum.
[C:/Users/erick/Desktop/TISC_OM_report/ProblemTester/recordExterFkt/modelica/ExpRecordPkg.mo:5:5-5:37:writable] Warning: Unused input variable x1 in function .ExpRecordPkg.addLibComplexNum.
[C:/Users/erick/Desktop/TISC_OM_report/ProblemTester/recordExterFkt/modelica/ExpRecordPkg.mo:6:5-6:37:writable] Warning: Unused input variable x2 in function .ExpRecordPkg.addLibComplexNum.
Error: Error building simulator. Buildlog: gcc -O3 -falign-functions -msse2 -mfpmath=sse -I\"C:/OpenModelica1.8.1//include/omc\" -I. -L\"C:/Users/erick/Desktop/TISC_OM_report/ProblemTester/recordExterFkt/modelica\" -c -o ExpRecordPkg.RecordExtFktTester.o ExpRecordPkg.RecordExtFktTester.c
In file included from ExpRecordPkg.RecordExtFktTester.c:15:
ExpRecordPkg.RecordExtFktTester_functions.c: In function '_ExpRecordPkg_addLibComplexNum':
ExpRecordPkg.RecordExtFktTester_functions.c:30: error: '_y' undeclared (first use in this function)
ExpRecordPkg.RecordExtFktTester_functions.c:30: error: (Each undeclared identifier is reported only once
ExpRecordPkg.RecordExtFktTester_functions.c:30: error: for each function it appears in.)
ExpRecordPkg.RecordExtFktTester_functions.c:32: error: 'struct ExpRecordPkg_ComplexRec' has no member named 'realComp_ext'
ExpRecordPkg.RecordExtFktTester_functions.c:32: error: 'struct ExpRecordPkg_ComplexRec' has no member named 'imagComp_ext'
ExpRecordPkg.RecordExtFktTester_functions.c:32: error: 'struct ExpRecordPkg_ComplexRec' has no member named 'realComp_ext'
ExpRecordPkg.RecordExtFktTester_functions.c:32: error: 'struct ExpRecordPkg_ComplexRec' has no member named 'imagComp_ext'
mingw32-make: * [ExpRecordPkg.RecordExtFktTester.o] Error 1

Thanks in advance,
Erick

Attachments (1)

recordExterFkt.zip (9.2 KB ) - added by e.da-silva 13 years ago.

Download all attachments as: .zip

Change History (5)

by e.da-silva, 13 years ago

Attachment: recordExterFkt.zip added

comment:1 by Martin Sjölund, 11 years ago

Cc: e.da-silva, → e.da-silva
Component: Backend

Smaller model showing this problem:

model M
  record R
    Real x;
  end R;
  function f
    input Real x;
    output R r;
  external "C" f(x,r.x) annotation(Include="void f(double x, void *s) {struct R {double x;};struct R *r = (struct R*) s;r->x = x;}");
  end f;
  R r = f(time);
end M;

comment:2 by Martin Sjölund, 11 years ago

Component: BackendCode Generation
Owner: changed from e.da-silva to Martin Sjölund
Status: newassigned

comment:3 by Martin Sjölund, 11 years ago

Actually, I am not convinced you are allowed to pass r.x here. Only identifiers, scalar constants and size is allowed. Otherwise you need to create a protected temporary variable.

model M
  record R
    Real x;
  end R;
  function f1
    input Real x;
    output R r;
  protected
    Real r_x = r.x;
    // Not allowed external "C" f(x,r.x) annotation(Include="void f(double x, double *d) {*d = x;}");
    external "C" f(x,r_x) annotation(Include="void f(double x, double *d) {*d = x;}");
  end f1;
  function f2
    input Real x;
    output R r;
    // OK
  external "C" f(x,r) annotation(Include="void f(double x, void *s) {struct R {double x;};struct R *r = (struct R*) s;r->x = x;}");
  end f2;
  R r1 = f1(time);
  R r2 = f2(time);
end M;

comment:4 by Martin Sjölund, 11 years ago

Resolution: invalid
Status: assignedclosed

An error message for this is now output in r18508.
// [flattening/modelica/external-functions/ExternalFunctionInvalidRecordComponent.mo:7:3-11:8:writable] Error: Expression y.x cannot be an external argument. Only simple identifiers, constant scalars, and size-expressions are allowed.

Note: See TracTickets for help on using tickets.