Modelica 外部函数:将C脚本中的头引用到已编译的dll

Modelica 外部函数:将C脚本中的头引用到已编译的dll,modelica,dymola,Modelica,Dymola,使用Dymola 2017 案例A)调用外部c脚本 我成功地实现了没有“#include”语句的简单外部c函数: Modelica函数: function chirp input Modelica.SIunits.AngularVelocity w_start; input Modelica.SIunits.AngularVelocity w_end; input Real A; input Real M; input Real t; output Real u &qu

使用Dymola 2017

案例A)调用外部c脚本

我成功地实现了没有“#include”语句的简单外部c函数:

Modelica函数:

function chirp

  input Modelica.SIunits.AngularVelocity w_start;
  input Modelica.SIunits.AngularVelocity w_end;
  input Real A;
  input Real M;
  input Real t;
  output Real u "output signal";

  external "C" u=chirp(w_start,w_end,A,M,t)
    annotation(IncludeDirectory="modelica://ExternalFuncTest/Resources/Source/", Include="#include \"chirp.c\"");

end chirp;
double chirp(double w1, double w2, double A, double M, double time)
{
  double res;
  res=A*cos(w1*time+(w2-w1)*time*time/(2*M));
    
  return res;
}
function bessel_Jn
  "Bessel function of the 1st kind (regular cylindrical) of order n"

  extends Modelica.Icons.Function;

  input Integer n;
  input Real x;
  output Real y;

  external "C" y=gsl_sf_bessel_Jn(n,x) annotation(LibraryDirectory="modelica://ExternalFuncTest/Resources/Source/gsl-1.8/", Library="libgsl");

end bessel_Jn;
function chirp

  input Modelica.SIunits.AngularVelocity w_start;
  input Modelica.SIunits.AngularVelocity w_end;
  input Real A;
  input Real M;
  input Real t;
  output Real u "output signal";

  external "C" u=chirp(w_start,w_end,A,M,t)
    annotation(LibraryDirectory="modelica://ExternalFuncTest/Resources/Source/gsl-1.8/", Library="libgsl",
               IncludeDirectory="modelica://ExternalFuncTest/Resources/Source/", Include="#include \"chirp.c\"");

end chirp;
#include <gsl/gsl_sf_bessel.h> //<-- note the additional header

double chirp(double w1, double w2, double A, double M, double time)
{
  double res;
  res=A*cos(w1*time+(w2-w1)*time*time/(2*M));
  return res;
}
C脚本:

function chirp

  input Modelica.SIunits.AngularVelocity w_start;
  input Modelica.SIunits.AngularVelocity w_end;
  input Real A;
  input Real M;
  input Real t;
  output Real u "output signal";

  external "C" u=chirp(w_start,w_end,A,M,t)
    annotation(IncludeDirectory="modelica://ExternalFuncTest/Resources/Source/", Include="#include \"chirp.c\"");

end chirp;
double chirp(double w1, double w2, double A, double M, double time)
{
  double res;
  res=A*cos(w1*time+(w2-w1)*time*time/(2*M));
    
  return res;
}
function bessel_Jn
  "Bessel function of the 1st kind (regular cylindrical) of order n"

  extends Modelica.Icons.Function;

  input Integer n;
  input Real x;
  output Real y;

  external "C" y=gsl_sf_bessel_Jn(n,x) annotation(LibraryDirectory="modelica://ExternalFuncTest/Resources/Source/gsl-1.8/", Library="libgsl");

end bessel_Jn;
function chirp

  input Modelica.SIunits.AngularVelocity w_start;
  input Modelica.SIunits.AngularVelocity w_end;
  input Real A;
  input Real M;
  input Real t;
  output Real u "output signal";

  external "C" u=chirp(w_start,w_end,A,M,t)
    annotation(LibraryDirectory="modelica://ExternalFuncTest/Resources/Source/gsl-1.8/", Library="libgsl",
               IncludeDirectory="modelica://ExternalFuncTest/Resources/Source/", Include="#include \"chirp.c\"");

end chirp;
#include <gsl/gsl_sf_bessel.h> //<-- note the additional header

double chirp(double w1, double w2, double A, double M, double time)
{
  double res;
  res=A*cos(w1*time+(w2-w1)*time*time/(2*M));
  return res;
}

案例B)调用.dll文件中的外部函数

我还成功地在编译的dll中调用了外部函数:

Modelica函数:

function chirp

  input Modelica.SIunits.AngularVelocity w_start;
  input Modelica.SIunits.AngularVelocity w_end;
  input Real A;
  input Real M;
  input Real t;
  output Real u "output signal";

  external "C" u=chirp(w_start,w_end,A,M,t)
    annotation(IncludeDirectory="modelica://ExternalFuncTest/Resources/Source/", Include="#include \"chirp.c\"");

end chirp;
double chirp(double w1, double w2, double A, double M, double time)
{
  double res;
  res=A*cos(w1*time+(w2-w1)*time*time/(2*M));
    
  return res;
}
function bessel_Jn
  "Bessel function of the 1st kind (regular cylindrical) of order n"

  extends Modelica.Icons.Function;

  input Integer n;
  input Real x;
  output Real y;

  external "C" y=gsl_sf_bessel_Jn(n,x) annotation(LibraryDirectory="modelica://ExternalFuncTest/Resources/Source/gsl-1.8/", Library="libgsl");

end bessel_Jn;
function chirp

  input Modelica.SIunits.AngularVelocity w_start;
  input Modelica.SIunits.AngularVelocity w_end;
  input Real A;
  input Real M;
  input Real t;
  output Real u "output signal";

  external "C" u=chirp(w_start,w_end,A,M,t)
    annotation(LibraryDirectory="modelica://ExternalFuncTest/Resources/Source/gsl-1.8/", Library="libgsl",
               IncludeDirectory="modelica://ExternalFuncTest/Resources/Source/", Include="#include \"chirp.c\"");

end chirp;
#include <gsl/gsl_sf_bessel.h> //<-- note the additional header

double chirp(double w1, double w2, double A, double M, double time)
{
  double res;
  res=A*cos(w1*time+(w2-w1)*time*time/(2*M));
  return res;
}

案例C)通过头调用外部C脚本,该脚本使用外部.dll中的函数

我现在想做的是创建一个c函数,它可以做更多有趣的事情。我目前的方法是在c函数中包含头文件,该函数引用已编译的dll(在本例中是GNU科学库的编译版本)。这个例子有一个标题(尽管它目前没有做任何事情)

Modelica函数:

function chirp

  input Modelica.SIunits.AngularVelocity w_start;
  input Modelica.SIunits.AngularVelocity w_end;
  input Real A;
  input Real M;
  input Real t;
  output Real u "output signal";

  external "C" u=chirp(w_start,w_end,A,M,t)
    annotation(IncludeDirectory="modelica://ExternalFuncTest/Resources/Source/", Include="#include \"chirp.c\"");

end chirp;
double chirp(double w1, double w2, double A, double M, double time)
{
  double res;
  res=A*cos(w1*time+(w2-w1)*time*time/(2*M));
    
  return res;
}
function bessel_Jn
  "Bessel function of the 1st kind (regular cylindrical) of order n"

  extends Modelica.Icons.Function;

  input Integer n;
  input Real x;
  output Real y;

  external "C" y=gsl_sf_bessel_Jn(n,x) annotation(LibraryDirectory="modelica://ExternalFuncTest/Resources/Source/gsl-1.8/", Library="libgsl");

end bessel_Jn;
function chirp

  input Modelica.SIunits.AngularVelocity w_start;
  input Modelica.SIunits.AngularVelocity w_end;
  input Real A;
  input Real M;
  input Real t;
  output Real u "output signal";

  external "C" u=chirp(w_start,w_end,A,M,t)
    annotation(LibraryDirectory="modelica://ExternalFuncTest/Resources/Source/gsl-1.8/", Library="libgsl",
               IncludeDirectory="modelica://ExternalFuncTest/Resources/Source/", Include="#include \"chirp.c\"");

end chirp;
#include <gsl/gsl_sf_bessel.h> //<-- note the additional header

double chirp(double w1, double w2, double A, double M, double time)
{
  double res;
  res=A*cos(w1*time+(w2-w1)*time*time/(2*M));
  return res;
}
C-script:

function chirp

  input Modelica.SIunits.AngularVelocity w_start;
  input Modelica.SIunits.AngularVelocity w_end;
  input Real A;
  input Real M;
  input Real t;
  output Real u "output signal";

  external "C" u=chirp(w_start,w_end,A,M,t)
    annotation(IncludeDirectory="modelica://ExternalFuncTest/Resources/Source/", Include="#include \"chirp.c\"");

end chirp;
double chirp(double w1, double w2, double A, double M, double time)
{
  double res;
  res=A*cos(w1*time+(w2-w1)*time*time/(2*M));
    
  return res;
}
function bessel_Jn
  "Bessel function of the 1st kind (regular cylindrical) of order n"

  extends Modelica.Icons.Function;

  input Integer n;
  input Real x;
  output Real y;

  external "C" y=gsl_sf_bessel_Jn(n,x) annotation(LibraryDirectory="modelica://ExternalFuncTest/Resources/Source/gsl-1.8/", Library="libgsl");

end bessel_Jn;
function chirp

  input Modelica.SIunits.AngularVelocity w_start;
  input Modelica.SIunits.AngularVelocity w_end;
  input Real A;
  input Real M;
  input Real t;
  output Real u "output signal";

  external "C" u=chirp(w_start,w_end,A,M,t)
    annotation(LibraryDirectory="modelica://ExternalFuncTest/Resources/Source/gsl-1.8/", Library="libgsl",
               IncludeDirectory="modelica://ExternalFuncTest/Resources/Source/", Include="#include \"chirp.c\"");

end chirp;
#include <gsl/gsl_sf_bessel.h> //<-- note the additional header

double chirp(double w1, double w2, double A, double M, double time)
{
  double res;
  res=A*cos(w1*time+(w2-w1)*time*time/(2*M));
  return res;
}

#include/我认为这只能通过相对include路径或实现未来Modelica语言规范3.4的未来工具来解决。有关Modelica语言规范的相应更新,请参阅。

您将include directory设置为
modelica://ExternalFuncTest/Resources/Source/gsl-1.8/
然后使用
#include

在目录gsl-1.8中是否真的有一个目录gsl-1.8(有些项目有这样的结构,但通常很少)?如果不是这样,则更改为
#include


我相信,在路径中也会搜索层次包含,因此这应该会起作用;否则,您可以始终将includeDirectory设置为
modelica://ExternalFuncTest/Resources/Source/gsl-1.8/gsl
和使用
#include

可以引用Modelica外部函数调用的c脚本中编译的库头

但是,仍然无法确定是否有有效的方法访问.dll。这将在后续问题中讨论

给出了允许识别头文件的解决方案。感谢所有帮助解决这个问题的人


步骤1)创建文件夹结构

Modelica会自动在默认目录中查找外部函数依赖项。第12.9.4节

Modelica查找编译库的默认位置是项目资源文件夹中名为
Library
的文件夹:

LibraryDirectory=”modelica://LibraryPackageName/Resources/Library“

对于头文件和c脚本,默认位置是项目资源文件夹中名为
Include
的文件夹:

IncludeDirectory=”modelica://LibraryPackageName/Resources/Include“

要指定替代目录,请遵循modelica规范文档。从Modelica规范3.3版本1起,您只能指定一个
库目录
和一个
包含目录
。尽管这可能在将来得到解决

文件夹总体结构摘要

步骤2)在上图中指定的位置创建Modelica函数和C脚本

以下是可供参考的示例

Modelica函数

C脚本

#包括
双啁啾(双w1,双w2,双A,双M,双时间)
{
双res;
res=A*cos(w1*time+(w2-w1)*time*time/(2*M));
返回res;
}

我以前看过那张罚单,我不太确定我的问题和那张罚单是同一件事。我试图把东西放在同一个目录中,但事情仍然不起作用,我认为这就是罚单所说的。我本以为最后一个示例会起作用(前提是标题位于我认为它们所在的位置)。因此,可能是:使用Dymola(?)支持提交一份错误报告,或者首先在另一个工具中尝试,以确保。@sjoelund.se我添加了一张图片,希望能够澄清文件夹结构的外观。这是否符合您的期望或我搞错了?@sjoelund.se我想我可能已经通过更改gsl标题文件夹的位置找到了解决方案。我会更新上面的帖子。我发誓我以前已经试过了,但现在已经可以用了,所以我一定是换了别的东西。我无法重现这个问题。但是,另一种解决方案是使用“gsl-1.8/gsl/gsl#u errno.h”代替。对于include,和“”之间的区别在于“”还相对于源文件进行搜索,源文件可能被视为chirp.c(因此人们通常将“”用于系统文件,将“”用于用户文件)。但是我看不出这有什么区别。你更改了DLL的位置。是否更新了LibraryDirectory?否gsl-1.8中没有目录gsl-1.8。我将库目录设置为
modelica://ExternalFuncTest/Resources/Source/gsl-1.8/
。包含目录为
modelica://ExternalFuncTest/Resources/Source/
以便拾取c脚本。这就是为什么我在标题中添加了
gsl-1.8
,希望它能在源代码文件夹中查找
gsl-1.8
,然后
gsl/gsl\u errno.h
。啊,我错过了源代码中的库。我相信还有另一个更简单的解决方案-将只是验证我改变了gsl头文件夹的位置,它现在可以工作了。我会用我发现的更新我的帖子。我仍然很好奇你的方法是什么。您知道默认的库和包含目录是什么,或者指定在哪里吗?我似乎无法在modelica规范中找到它。默认值为:modelica://LibraryName/Resources/Include 及modelica://LibraryName/Resources/Library 从12.9.4开始,现在头的问题解决了,我现在尝试从dll调用一个函数(这就是头发生的全部原因)。我对原来的问题进行了更新。你能看一下吗?