Внешние функции: альтернативный метод использования .dll из C-скрипта

Это дополнительный вопрос к External Functions: Reference headers in C-скрипт для скомпилированной dll.

Этот вопрос о переполнении стека использует вызов внешней функции Modelica для c-script. Затем этот c-скрипт использует c-функции, содержащиеся в .dll. Ниже приведен первоначальный предпочтительный метод, который я пробовал, и рабочая попытка, которую я не предпочитаю.


Первоначальная попытка:

Следующий код не будет работать. Мое предположение заключалось в том, что, поскольку я загрузил библиотеку .dll libgsl в Modelica, я мог бы просто использовать заголовки в C-script для использования вызовов функций из этой .dll. Однако в файле dslog.txt указано, что он не может распознать gsl_sf_bessel_j0. Судя по всему, C-скрипт ничего не знает о libgsl.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(Library="libgsl", Include="#include \"chirp.c\"");
end chirp;

C-скрипт:

#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?

Функция модели:

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-скрипт:

#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;
}

person Scott G    schedule 16.12.2016    source источник