Сам вызов функций WinAPI делается на Cи (на примере MessageBox):
// Файл: winapi.c
// *** Вызовы функций Windows API ***
#include <windows.h>
int c_messagebox_(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
{
return MessageBox(hWnd, lpText, lpCaption, uType);
}
Названия функций, которые мы затем будем вызывать из Фортран (в примере – c_messagebox_
), должны заканчиваться знаком подчеркивания. В Фортране его не будет – это связано с принципами линковки в GCC
.
Для доступа к этим функциям из Фортран-программ целесообразно сделать модуль с обертками:
! Файл: windows.f08
! *** Модуль с интерфейсом к некоторым функциям Windows API ***
module Windows
use iso_c_binding
implicit none
integer(kind=C_LONG), parameter, private :: HWND_DESKTOP = '00000000'X
integer(kind=C_LONG), parameter, private :: MB_OK = '00000000'X
integer(kind=C_LONG), parameter, private :: MB_ICONERROR = '00000010'X
integer(kind=C_LONG), parameter, private :: MB_ICONINFORMATION = '00000040'X
interface
function c_messagebox(hWnd, lpText, lpCaption, uType)
use iso_c_binding
integer(kind=C_LONG) :: c_messagebox
integer(kind=C_LONG), value :: hWnd, uType
character(kind=C_CHAR, len=*) :: lpText, lpCaption
endfunction
endinterface
contains
subroutine MsgErr(str) ! Выводит простой MessageBox с ошибкой
character(*) :: str
integer :: res
res = c_messagebox(HWND_DESKTOP, str // C_NULL_CHAR, &
"Ошибка" // C_NULL_CHAR, MB_ICONERROR + MB_OK)
endsubroutine
subroutine MsgInf(str) ! Выводит простой MessageBox c информацией
character(*) :: str
integer :: res
res = c_messagebox(HWND_DESKTOP, str // C_NULL_CHAR, &
"Информация" // C_NULL_CHAR, MB_ICONINFORMATION + MB_OK)
endsubroutine
endmodule
Здесь вызов функций из модуля на Си осуществляется через interface
с указанием специальных разновидностей типов (C_LONG
, C_CHAR
), определенных для совместимости с Си в модуле iso_c_binding
, входящим в GCC
.
NB! В процедурах-обертках к строкам приходится добавлять C_NULL_CHAR
.
Для проверки:
! Файл: test.f08
program Test
use Windows
call MsgInf("Это информация.")
call MsgErr("А это ошибка!")
endprogram
Компилируем и запускам:
gcc -c winapi.c
gfortran -c windows.f08
gfortran -c test.f08
gfortran *.o -o test.exe
test.exe
Если все хорошо, получаем:
Получилось!
ОтветитьУдалитьПришлось заменить '00000000'X '00000010'X '00000040'X на 0 16 64.
Русский текст перевирает.
gfortran *.o -o test.exe заменить на gfortran winapi.o windows.o test.o -o test.exe