Внешние функции: альтернативный метод использования.dll из C-скрипта
Это сопутствующий вопрос к Внешним функциям: Ссылка заголовков в C-скрипте на скомпилированную dll.
Этот вопрос переполнения стека использует вызов внешней функции Modelica для c-скрипта. Затем этот c-скрипт использует c-функции, содержащиеся в.dll. Ниже приведен первоначальный предпочтительный метод, который я пробовал, и рабочая попытка, которую я не предпочитаю.
Начальная попытка:
Следующий код не будет работать. Мое предположение было, так как я загрузил библиотеку.dll libgsl
в Modelica я мог бы просто использовать заголовки в C-скрипте, чтобы использовать вызовы функций из этого.dll. Однако в файле dslog.txt указано, что он не может распознать gsl_sf_bessel_j0
, По-видимому, C-скрипт ничего не знает о libgsl.dll
что я указал в Modelica.
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 chirp2(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(res);
return y;
}
Рабочая попытка:
Чтобы использовать.dll во внешнем вызове функции с использованием C-скрипта, я счел необходимым загрузить библиотеку самостоятельно, используя LoadLibrary
команда.
Этот метод действительно необходим? Это намного сложнее, чем моя первоначальная попытка, которая, как я надеялся, сработает там, где я думал, что Modelica содержит необходимые "ноу-хау" для загрузки.dll.
Бонус: кажется, что существует способ отправить сообщения об ошибках обратно в Modelica. void ModelicaVFormatError (const char * string, va_list). Знаете примерный пример его использования, чтобы я мог заменить операторы printf, которые, похоже, ничего не отправляют обратно в Modelica?
Modelica Функция:
function chirp
input Modelica.SIunits.AngularVelocity w_start;
input Modelica.SIunits.AngularVelocity w_end;
input Real A;
input Real M;
input Real t;
input String fileName= Modelica.Utilities.Files.loadResource("modelica://ExternalFuncTest/Resources/Library/libgsl.dll") "Full file name for GSL library";
output Real u "output signal";
external "C" u=chirp(w_start,w_end,A,M,t)
annotation(Include="#include \"chirp.c\""); // <-- Removed Library reference
end chirp;
C-Script:
#include <windows.h>
#include <stdio.h>
typedef double (__cdecl *BESSEL)(const double);
double chirp3(double w1, double w2, double A, double M, double time, const char* fileName)
{
HINSTANCE hinstLib;
BESSEL bessel_J0;
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
// Get a handle to the DLL module.
hinstLib = LoadLibrary(fileName);
// If the handle is valid, try to get the function address.
double res;
double y = 0;
res=A*cos(w1*time+(w2-w1)*time*time/(2*M));
if (hinstLib != NULL)
{
bessel_J0 = (BESSEL) GetProcAddress(hinstLib, "gsl_sf_bessel_j0");
// If the function address is valid, call the function.
if (NULL != bessel_J0)
{
fRunTimeLinkSuccess = TRUE;
printf("Success loading library method.\n"); //<-- Alternative to send message back to Modelica log file?
y = bessel_J0(res);
} else
{
printf("Failed to load library\n"); //<-- Alternative to send message back to Modelica log file?
}
// Free the DLL module.
fFreeResult = FreeLibrary(hinstLib);
}
return y;
}