Бывает, что у нас имеются библиотеки .a
только для статической линковки, а мы бы хотели вместо них иметь DLL и подключать ее динамически.
Примером может быть библиотека линейной алгебры LAIPE2 с стайта www.equation.com.
Оказывается, из .a
очень просто сделать DLL автоматически.
Нам потребуется файл-заглушка Dllmain.f90
с пустой процедурой:
subroutine my_dll_main()
endsubroutine
Откомпилируем его в DLL с подключением соответствующих библиотек (в данном примере – liblaipe2.a
и нужная ей для работы libneuloop4.a
):
gfortran dllmain.f90 -shared -o laipe2.dll -Wl,-export-all-symbols
-Wl,-enable-auto-import -Wl,-no-undefined -Wl,--enable-runtime-pseudo-reloc
-Wl,-whole-archive liblaipe2.a libneuloop4.a -Wl,-no-whole-archive
Тут довольно много ключей для линковщика – я их взял из примера, найденного в интернете, в смысл особо не погружался. Главное, что это работает.
Протестировать полученную DLL можно дополнив пример из прошлого поста:
! Вставка в файл LapackFromDll.F90:
...
!> Интерфейсы функций LAIPE2
abstract interface
subroutine laipe_use_(N)
integer N
endsubroutine
subroutine laipe_done_()
endsubroutine
subroutine laipe_DAG_8_(A_io, N_i, X_io, NoGood_o)
integer NoGood_o, N_i
double precision A_io(*), X_io(*)
endsubroutine
endinterface
!> Процедуры-указатели на функции LAIPE2
procedure(laipe_use_) , pointer :: laipe_use
procedure(laipe_done_) , pointer :: laipe_done
procedure(laipe_DAG_8_), pointer :: laipe_DAG_8
...
! Вставка в файл LinTest.F90:
...
call LoadDll(LinAlg_dll, "laipe2.dll")
call DllProcAssoc(LinAlg_dll, laipe_use, "laipe$use_")
call DllProcAssoc(LinAlg_dll, laipe_done, "laipe$done_")
call DllProcAssoc(LinAlg_dll, laipe_DAG_8, "laipe$solution_dag_8_")
call laipe_use(8)
A = A0 ; X = B
call laipe_DAG_8(A, n, X, info)
print "(' *** Решение с помощью laipe2.dll (info = ',i1,'):')", info
print FRM, X
call laipe_done()
call FreeDll(LinAlg_dll)
...
Комментариев нет:
Отправить комментарий