Внешние функции: Ссылка заголовков в C-скрипте на скомпилированную DLL
Использование Dymola 2017.
Случай А) Вызов внешнего c-скрипта
Я успешно реализовал простые внешние функции c, которые не имеют операторов "# include <->":
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;
C-скрипт:
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;
}
Случай Б) Вызов внешней функции в DLL-файле.
Я также имел успех в вызове внешних функций в скомпилированной DLL:
Modelica Функция:
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;
Случай C) Вызов внешнего c-скрипта, который использует функции из внешнего.dll через заголовки
Что я хочу сделать сейчас, это создать функцию переменного тока, которая делает больше интересных вещей. Мой текущий подход заключается в том, чтобы включить заголовочные файлы в функцию 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(LibraryDirectory="modelica://ExternalFuncTest/Resources/Source/gsl-1.8/", Library="libgsl",
IncludeDirectory="modelica://ExternalFuncTest/Resources/Source/", Include="#include \"chirp.c\"");
end chirp;
C-cript:
#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-скрипту и.dll.
Неправильный путь: обратите внимание, что папка заголовка gsl находится в папке gsl-1.8
Правильный путь: обратите внимание, что папка заголовка gsl находится на том же уровне, что и папка gsl-1.8.
ОБНОВЛЕНИЕ: заголовок работает, но вызов функции приводит к сбою перевода
Я обновил c-скрипт, чтобы теперь вызывать функцию, которая должна обрабатываться заголовком. В его текущем состоянии это не будет работать. Возможно, он не может найти файл.dll, хотя он указан в коде modelica? Нужно ли включать команду.dll в c-скрипты?
#include <gsl/gsl_sf_bessel.h>
double chirp(double w1, double w2, double A, double M, double time)
{
double res;
double y;
res=A*cos(w1*time+(w2-w1)*time*time/(2*M));
y = gsl_sf_bessel_j0(time); // <-- Calls a function from the .dll file using the header
return res;
}
3 ответа
Возможна ссылка на заголовки скомпилированной библиотеки из c-скриптов, которые вызываются вызовом внешней функции Modelica.
Однако до сих пор не определено, существует ли эффективный способ доступа к.dll. Это обсуждается в следующем вопросе. Внешние функции: альтернативный метод использования.dll из C-скрипта.
Представлено решение, позволяющее распознавать заголовочные файлы. Спасибо всем, кто откликнулся, помогая разобраться в этом.
Шаг 1) Создайте структуру папок
Modelica автоматически ищет в каталогах по умолчанию внешние зависимости функций. Раздел 12.9.4 https://modelica.org/documents/ModelicaSpec33Revision1.pdf
Местоположение по умолчанию, которое Modelica ищет скомпилированные библиотеки, - это папка с именем Library
в папке "Ресурсы" вашего проекта:
LibraryDirectory="modelica://LibraryPackageName/Resources/Library"
Для заголовочных файлов и c-скриптов местоположением по умолчанию является папка с именем Include
в папке "Ресурсы" вашего проекта:
IncludeDirectory="modelica://LibraryPackageName/Resources/Include"
Чтобы указать альтернативные каталоги, следуйте документу спецификации modelica. Начиная с спецификации Modelica 3.3 Rev 1 вы можете указать только один LibraryDirectory
и один IncludeDirectory
, Хотя это может быть решено в будущем https://trac.modelica.org/Modelica/ticket/2103.
Шаг 2) Создайте функцию Modelica и C-Scripts в местах, указанных на изображении выше
Ниже приведены примеры, которые можно использовать для справки.
Функция 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(Library="libgsl",Include="#include \"chirp.c\"");
end chirp;
C-Script
#include <gsl/gsl_sf_bessel.h>
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;
}
Вы устанавливаете каталог включения на modelica://ExternalFuncTest/Resources/Source/gsl-1.8/
а затем использовать #include <gsl-1.8/gsl/gsl_errno.h>
У вас действительно есть каталог gsl-1.8 в каталоге gsl-1.8 (в некоторых проектах такая структура есть - но обычно это редко)? Если это не так, измените на #include <gsl/gsl_errno.h>
,
Я полагаю, что иерархические включения также ищутся в пути и, таким образом, это должно работать; в противном случае вы всегда можете установить для includeDirectory значение modelica://ExternalFuncTest/Resources/Source/gsl-1.8/gsl
и использовать #include <gsl_errno.h>
,
Я считаю, что это может быть решено только с помощью относительных путей включения или будущих инструментов, которые реализуют будущую спецификацию языка Modelica 3.4. См. https://trac.modelica.org/Modelica/ticket/2103 для соответствующего обновления спецификации языка Modelica.