SoLL06
Newbie | Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору Описываю довольно распространённую проблему. Есть фортран, на котором написано много программ и который заточен для вычислений. Есть Delphi, с помощью которого очень удобно делать интерфейс (ну вообще много чего на нём делать легко и удобно, но в данному случае просто речь идёт про интерфейс). Вопрос: как бы сделать так, чтобы прогать на фортране, и иметь интерфейс Delphi? Ответ очевиден: надо создать DLL в DELPHI с функцией, которая создаёт форму. И вызывать эту функцию из фортрана. В интернете описываются решения, но везде какими-то урывками. Мне пришлось по крупицам собирать ото всюду, а потом ещё и отлаживать, т.к. не всё что предлагается лично у меня работает. Использую VS2013, Intel Parallel Studio XE 2015 и RAD Studio Xe3. Вот готовые коды для использования Для начала привожу код DLL с функций и процедурой library Project1; uses System.SysUtils, System.Classes; {$R *.res} function apb(a, b: double): double; stdcall; begin result := a + b; end; procedure apbp(var a, b, c: integer); cdecl; begin c := a + b; end; exports apb, apbp; begin end. Код фортрана для вызова процедуры program Console1 use msfwin implicit none interface subroutine apbp(a1, a2, a3) !DEC$ATTRIBUTES DLLIMPORT :: apbp integer a1, a2, a3 end subroutine end interface integer v1, v2 integer ret, hMod pointer (hProc1, apbp) hMod = LoadLibrary("c:\projects\proj_1\win32\debug\project1.dll") ! здесь путь к DLL hProc1 = GetProcAddress(hMod, "apbp") v1 = 4 v2 = 2 print *, v1 call apbp(v1, v2, v1) print *, v1 ret=FreeLibrary(hMod) end program Console1 Код фортрана для вызова функции program Console1 use msfwin implicit none interface real*8 function apb(a1, a2) !DEC$ATTRIBUTES DLLIMPORT, stdcall :: apb real*8 a1, a2 end function end interface real*8 v1, v2, v3 integer ret, hMod pointer (hProc1, apb) hMod = LoadLibrary("c:\projects\proj_1\win32\debug\project1.dll") hProc1 = GetProcAddress(hMod, "apb") v1 = 4.0 v3 = apb(v1, 3.0) print *, v3 ret=FreeLibrary(hMod) end program Console1 Обращаю внимание, что тип integer совпадает, а для double надо использовать real*8. Теперь про создание формы library Project1; uses System.SysUtils, System.Classes, forms, windows, Vcl.Dialogs, Unit1 in '..\Unit1.pas' {Form1}; var Form1: TForm1; {$R *.res} procedure showfrm(var cc: integer); cdecl; var h: HWND; begin form1 := TForm1.Create(application); form1.Showmodal; cc := strtoint(form1.Edit1.Text); end; exports showfrm; begin end. При создании DLL в проект нужно добавить файл с формой. В данном случае это Unit1.pas. Вообще так будет работать, но лучше, как мне кажется вместе с необходимыми параметрами в showfrm передавать ещё и handle окна программы фортрана и перед TForm1.Create добавить строчку application.handle := phandle, где phandle - это handle окна программы фортрана, передаваемый в качестве параметра. А в фотране это делается так v2 = GetForegroundWindow() Вот собственно и всё, чем я хотел поделиться с теми, кто так же как я в будущем будет искать как сделать то, что я описал. |