Создание DLL

Создаем проект типа Fortran DLL. Я использую среду Code::Blocks, но и в других средах, работающих с Fortran-ом, есть аналогичные виды проектов. Назовем проект mydll.

Наша библиотека будет содержать всего одну функцию (пример заимствован из книги Артемова):

real function F(x)
!$ ATTRIBUTES DLLEXPORT, STDCALL :: F
  real x
  F = x*x
end function F

Сохраним ее в файле funcdll.f95, который добавим в проект.

Символ $ указывает на то, что после ! идет не обычный комментарий, а метакоманда (вместо одиночного доллара можно указывать также тип компилятора: MS$, GCC$ или DEC$, но особой роли это не играет). Атрибут DLLEXPORT говорит о том, что функция F будет экспортироваться из библиотеки mydll.dll и использоваться другой программой. Атрибут STDCALL определяет тип соглашения о вызове функции и передачи в нее аргументов. Для использования библиотеки из программы на Fortran-е он, вообще говоря, не нужен. Но у других языков свои соглашения, так что рано или поздно указывать нечто подобное придется.

Транслируем проект. В результате будут получены 3 файла: mydll.dll, libmydll.a и libmydll.def. Они нам понадобятся в дальнейшем.

Вызов функции из DLL

Создадим консольное приложение (в Code::Blocks это Fortran Application) use_dll со следующей программой

program use_dll
  interface
    real function F(x) !$ ATTRIBUTES DLLIMPORT :: F
      real x
    end function F
  end interface

  write(*,*) "Result is ", F(25.)
  re_i = system("pause")
end

В блоке interface описан интерфейс вызываемой функции. Атрибут DLLIMPORT указывает на то, что функция импортируется из библиотеки DLL. Далее следует вызов функции.

Чтобы все это сработало нужно обеспечить доступность .a-файла (или .lib-файла) на этапе компоновки и .dll-файла — на этапе выполнения. Проще всего для этого скопировать в папку с исполняемым файлом проекта use_dll.exe (Debug или Release) полученные ранее mydll.dll, libmydll.a и libmydll.def. Кроме того, в опциях компоновщика (Project->Build Options, вкладка Linker Settins) нужно указать путь к libmydll.a.

Вызов собранной программы дает следующий результат:

res.png

Используя use_dll.exe, не забудьте скопировать и положить в доступное для системы место (например, в общую с use_dll.exe папку) файл библиотеки mydll.dll. Иначе будет выдано сообщение об ошибке.

И еще проще — без метакоманд

Но есть и более простой путь. Если вы создаете DLL, которую планируете использовать только из Fortran-а, то никаких метакоманд указывать не обязательно.

Создаем библиотеку mydll.dll из функции:

real function F(x)
  real x
  F = x*x
end function F

Как и раньше создаем приложение use_dll, копируем файлы библиотек в папку с исполняемым файлом и подключаем библиотеку в опциях компоновщика. Однако теперь код основной программы не будет содержать метакоманд, но только описание функции F как внешней (external):

program use_dyn_dll
  real, external :: f

  write(*,*) "Result is ", f(25.0)
  re_i = system("pause")
end program use_dyn_dll


Комментарии

comments powered by Disqus