从外部 C 函数返回 Modelica 记录时出错
Error Returning Modelica Record from External C Function
我已经编写了一个 C dll 函数,我想从 Modelica 调用它,并希望它成为 return Modelica 记录。
根据 "Modelica by Example" 书中描述的 data mapping,我在我的 C header 中定义了一个结构,我的函数 return 是一个指向该结构的指针。您可以在下面看到header内容:
#ifdef NZ1MAP_EXPORTS
#define NZ1MAP_API __declspec(dllexport)
#else
#define NZ1MAP_API __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C" {
#endif
// Define struct to match the SpeedlineVectors record in Modelica.
typedef struct
{
double Mach;
double PRVposition;
double DiffuserGap;
double Theta[24];
double Omega[24];
double MapEfficiency[24];
double OmegaStall[24];
} SpeedlineVectors;
NZ1MAP_API SpeedlineVectors* GetNZ1SpeedlineVectors_External(double Mach, double DiffuserGapFraction);
#ifdef __cplusplus
}
#endif
在 Dymola 中,我创建了以下记录:
record SpeedlineVectors
"Mach, PRV position, Diffuser Gap, and Vectors of Theta, Omega, Map Efficiency, Omega Stall"
Real Mach "impeller machine Mach";
Real PRVposition "PRV position, 0 = fully closed, 1 = fully open";
Real DiffuserGap
"Diffuser gap, 0 = fully closed, 1 = fully open, typical minimum = 0.05";
Real Theta[24] "vector of non-dimensional flow coefficients along speed line";
Real Omega[24] "vector of non-dimensional head coefficients along speed line";
Real MapEfficiency[24]
"vector of isentropic efficiency normalized to tip Reynolds number of 1E6 along speed line";
Real OmegaStall[24]
"vector of non-dimensional head where stall is expected to begin along speed line";
end SpeedlineVectors;
并且我创建了应该调用外部 C dll 和 return 一条 "SpeedlineVectors" 记录的函数:
function GetNZ1SpeedlineVectors_External
"Get NZ1 speedline array from external C function"
input Real operatingMach "Machine Mach number";
input Real diffuserGapFraction "Diffuser gap open fraction, 0 to 1";
output SpeedlineVectors speedlineVectors "speedlineVectors record";
external "C" speedlineVectors = GetNZ1SpeedlineVectors_External(operatingMach, diffuserGapFraction);
annotation(Include="#include <NZ1Map.h>", Library="NZ1Map");
end GetNZ1SpeedlineVectors_External;
我建立了下面的简单测试模型:
model GetNZ1SpeedlineVectors_Tester
Real mach = 1.32;
Real diffuserGapFraction = 0.50;
SpeedlineVectors myVectors;
equation
myVectors = GetNZ1SpeedlineVectors_External(mach, diffuserGapFraction);
annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
coordinateSystem(preserveAspectRatio=false)));
end GetNZ1SpeedlineVectors_Tester;
当我尝试 运行 测试模型时,我从 Dymola 收到以下错误消息:
Compiling and linking the model (Visual C++).
dsmodel.c
dsmodel.c(74) : error C2440: '=' : cannot convert from 'SpeedlineVectors *' to 'DymStruc0'
Error generating Dymosim.
我也尝试调整 C 函数 return 以便它直接 return 结构而不是指向结构的指针,但我收到类似的错误消息:
dsmodel.c(74) : error C2440: '=' : cannot convert from 'SpeedlineVectors' to 'DymStruc0'
关于必须对来自外部 C 函数的 Modelica 记录执行哪些操作的任何提示?
谢谢,
贾斯汀
根据 Modelica 规范第 12.9.1.3 节,当从外部函数返回时,无法映射记录中的数组。您也可以尝试使用外部对象:https://build.openmodelica.org/Documentation/ModelicaReference.Classes.ExternalObject.html
作为我的案例的解决方法,我能够通过更改外部函数来解决问题。而不是 returning 映射到记录的结构中的数组(感谢 Shaga 指出根据 modelica 规范不支持),函数更改为 return void 有四个输出数组。
C 头文件中的新函数定义是:
NZ1MAP_API void GetNZ1SpeedlineVectors_External(double Mach, double DiffuserGapFraction, double ThetaVector[], size_t SizeOfThetaVector, double OmegaVector[], size_t SizeOfOmegaVector, double MapEfficiencyVector[], size_t SizeOfMapEfficiencyVector, double OmegaStallVector[], size_t SizeOfOmegaStallVector);
C文件中的C函数定义为:
NZ1MAP_API void GetNZ1SpeedlineVectors_External(double Mach, double DiffuserGapFraction,
double thetaVector[], size_t thetaVectorSize, // thetaVector[] is equivalent to double* thetaVector
double omegaVector[], size_t omegaVectorSize,
double efficiencyVector[], size_t efficiencyVectorSize,
double omegaStallVector[], size_t omegaStallVectorSize)
modelica函数如下图:
function GetNZ1SpeedlineVectors_External
"Get NZ1 speedline array from external C function"
input Real operatingMach "Machine Mach number";
input Real diffuserGapFraction "Diffuser gap open fraction, 0 to 1";
output Real ThetaVector[24]
"vector of non-dimensional flow coefficients along speedline";
output Real OmegaVector[24]
"vector of non-dimensional head coefficients along speedline";
output Real MapEfficiencyVector[24]
"vector of non-dimensional map efficiency along speedline";
output Real OmegaStallVector[24] "vector of omega stall along speedline";
external "C" GetNZ1SpeedlineVectors_External(operatingMach, diffuserGapFraction, ThetaVector, size(ThetaVector,1), OmegaVector, size(OmegaVector,1), MapEfficiencyVector, size(MapEfficiencyVector,1), OmegaStallVector, size(OmegaStallVector, 1));
annotation(Include = "#include <NZ1Map.h>", Library="NZ1Map");
end GetNZ1SpeedlineVectors_External;
调用modelica函数的测试模型为:
model NZ1_External "NZ1 External Dll"
extends SpeedlineVectorsBase;
parameter Real inputMach = 1.4;
parameter Real inputDiffuserGapFraction = 1;
equation
Mach = inputMach;
PRVposition = 1;
DiffuserGapFraction = inputDiffuserGapFraction;
(ThetaVector, OmegaVector, MapEfficiencyVector, OmegaStallVector) =
GetNZ1SpeedlineVectors_External(Mach, DiffuserGapFraction);
end NZ1_External;
我希望这可以帮助其他人了解他们如何 return 从外部函数到 modelica 的多个数组,因为 modelica 不会将数组 return 映射为结构的一部分。
谢谢,
贾斯汀
您可以通过在外部函数调用中使用分层名称来向 Modelica 函数的用户隐藏多个数组。
function GetNZ1SpeedlineVectors_External
input Real operatingMach "Machine Mach number";
input Real diffuserGapFraction "Diffuser gap open fraction, 0 to 1";
output SpeedlineVectors speedlineVectors "speedlineVectors record";
external "C" GetNZ1SpeedlineVectors_External(operatingMach,diffuserGapFraction, speedLineVectors.ThetaVector, size(speedLineVectors.ThetaVector,1), ...);
annotation(Include="#include <NZ1Map.h>", Library="NZ1Map");
end GetNZ1SpeedlineVectors_External;
这是 Modelica 3.3 修订版 1 中添加的新功能,https://trac.modelica.org/Modelica/ticket/351
并且应该从 Dymola 2015 开始可用。
我已经编写了一个 C dll 函数,我想从 Modelica 调用它,并希望它成为 return Modelica 记录。
根据 "Modelica by Example" 书中描述的 data mapping,我在我的 C header 中定义了一个结构,我的函数 return 是一个指向该结构的指针。您可以在下面看到header内容:
#ifdef NZ1MAP_EXPORTS
#define NZ1MAP_API __declspec(dllexport)
#else
#define NZ1MAP_API __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C" {
#endif
// Define struct to match the SpeedlineVectors record in Modelica.
typedef struct
{
double Mach;
double PRVposition;
double DiffuserGap;
double Theta[24];
double Omega[24];
double MapEfficiency[24];
double OmegaStall[24];
} SpeedlineVectors;
NZ1MAP_API SpeedlineVectors* GetNZ1SpeedlineVectors_External(double Mach, double DiffuserGapFraction);
#ifdef __cplusplus
}
#endif
在 Dymola 中,我创建了以下记录:
record SpeedlineVectors
"Mach, PRV position, Diffuser Gap, and Vectors of Theta, Omega, Map Efficiency, Omega Stall"
Real Mach "impeller machine Mach";
Real PRVposition "PRV position, 0 = fully closed, 1 = fully open";
Real DiffuserGap
"Diffuser gap, 0 = fully closed, 1 = fully open, typical minimum = 0.05";
Real Theta[24] "vector of non-dimensional flow coefficients along speed line";
Real Omega[24] "vector of non-dimensional head coefficients along speed line";
Real MapEfficiency[24]
"vector of isentropic efficiency normalized to tip Reynolds number of 1E6 along speed line";
Real OmegaStall[24]
"vector of non-dimensional head where stall is expected to begin along speed line";
end SpeedlineVectors;
并且我创建了应该调用外部 C dll 和 return 一条 "SpeedlineVectors" 记录的函数:
function GetNZ1SpeedlineVectors_External
"Get NZ1 speedline array from external C function"
input Real operatingMach "Machine Mach number";
input Real diffuserGapFraction "Diffuser gap open fraction, 0 to 1";
output SpeedlineVectors speedlineVectors "speedlineVectors record";
external "C" speedlineVectors = GetNZ1SpeedlineVectors_External(operatingMach, diffuserGapFraction);
annotation(Include="#include <NZ1Map.h>", Library="NZ1Map");
end GetNZ1SpeedlineVectors_External;
我建立了下面的简单测试模型:
model GetNZ1SpeedlineVectors_Tester
Real mach = 1.32;
Real diffuserGapFraction = 0.50;
SpeedlineVectors myVectors;
equation
myVectors = GetNZ1SpeedlineVectors_External(mach, diffuserGapFraction);
annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
coordinateSystem(preserveAspectRatio=false)));
end GetNZ1SpeedlineVectors_Tester;
当我尝试 运行 测试模型时,我从 Dymola 收到以下错误消息:
Compiling and linking the model (Visual C++).
dsmodel.c
dsmodel.c(74) : error C2440: '=' : cannot convert from 'SpeedlineVectors *' to 'DymStruc0'
Error generating Dymosim.
我也尝试调整 C 函数 return 以便它直接 return 结构而不是指向结构的指针,但我收到类似的错误消息:
dsmodel.c(74) : error C2440: '=' : cannot convert from 'SpeedlineVectors' to 'DymStruc0'
关于必须对来自外部 C 函数的 Modelica 记录执行哪些操作的任何提示?
谢谢, 贾斯汀
根据 Modelica 规范第 12.9.1.3 节,当从外部函数返回时,无法映射记录中的数组。您也可以尝试使用外部对象:https://build.openmodelica.org/Documentation/ModelicaReference.Classes.ExternalObject.html
作为我的案例的解决方法,我能够通过更改外部函数来解决问题。而不是 returning 映射到记录的结构中的数组(感谢 Shaga 指出根据 modelica 规范不支持),函数更改为 return void 有四个输出数组。
C 头文件中的新函数定义是:
NZ1MAP_API void GetNZ1SpeedlineVectors_External(double Mach, double DiffuserGapFraction, double ThetaVector[], size_t SizeOfThetaVector, double OmegaVector[], size_t SizeOfOmegaVector, double MapEfficiencyVector[], size_t SizeOfMapEfficiencyVector, double OmegaStallVector[], size_t SizeOfOmegaStallVector);
C文件中的C函数定义为:
NZ1MAP_API void GetNZ1SpeedlineVectors_External(double Mach, double DiffuserGapFraction,
double thetaVector[], size_t thetaVectorSize, // thetaVector[] is equivalent to double* thetaVector
double omegaVector[], size_t omegaVectorSize,
double efficiencyVector[], size_t efficiencyVectorSize,
double omegaStallVector[], size_t omegaStallVectorSize)
modelica函数如下图:
function GetNZ1SpeedlineVectors_External
"Get NZ1 speedline array from external C function"
input Real operatingMach "Machine Mach number";
input Real diffuserGapFraction "Diffuser gap open fraction, 0 to 1";
output Real ThetaVector[24]
"vector of non-dimensional flow coefficients along speedline";
output Real OmegaVector[24]
"vector of non-dimensional head coefficients along speedline";
output Real MapEfficiencyVector[24]
"vector of non-dimensional map efficiency along speedline";
output Real OmegaStallVector[24] "vector of omega stall along speedline";
external "C" GetNZ1SpeedlineVectors_External(operatingMach, diffuserGapFraction, ThetaVector, size(ThetaVector,1), OmegaVector, size(OmegaVector,1), MapEfficiencyVector, size(MapEfficiencyVector,1), OmegaStallVector, size(OmegaStallVector, 1));
annotation(Include = "#include <NZ1Map.h>", Library="NZ1Map");
end GetNZ1SpeedlineVectors_External;
调用modelica函数的测试模型为:
model NZ1_External "NZ1 External Dll"
extends SpeedlineVectorsBase;
parameter Real inputMach = 1.4;
parameter Real inputDiffuserGapFraction = 1;
equation
Mach = inputMach;
PRVposition = 1;
DiffuserGapFraction = inputDiffuserGapFraction;
(ThetaVector, OmegaVector, MapEfficiencyVector, OmegaStallVector) =
GetNZ1SpeedlineVectors_External(Mach, DiffuserGapFraction);
end NZ1_External;
我希望这可以帮助其他人了解他们如何 return 从外部函数到 modelica 的多个数组,因为 modelica 不会将数组 return 映射为结构的一部分。
谢谢, 贾斯汀
您可以通过在外部函数调用中使用分层名称来向 Modelica 函数的用户隐藏多个数组。
function GetNZ1SpeedlineVectors_External
input Real operatingMach "Machine Mach number";
input Real diffuserGapFraction "Diffuser gap open fraction, 0 to 1";
output SpeedlineVectors speedlineVectors "speedlineVectors record";
external "C" GetNZ1SpeedlineVectors_External(operatingMach,diffuserGapFraction, speedLineVectors.ThetaVector, size(speedLineVectors.ThetaVector,1), ...);
annotation(Include="#include <NZ1Map.h>", Library="NZ1Map");
end GetNZ1SpeedlineVectors_External;
这是 Modelica 3.3 修订版 1 中添加的新功能,https://trac.modelica.org/Modelica/ticket/351 并且应该从 Dymola 2015 开始可用。