Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: ActiveX/СОМ/CORBA > вызов Fortran из Delphi


Автор: OK54 25.10.2014, 11:11
Добрый день!

Есть рабочая программа на Delphi, работающая с dll фортран. последних исходников dll нет. 
Пытаюсь вытащить этот модуль в другую программу - выдает ошибку "... access violation at .... read of address ..." (см. рисунок). Дело в том, что я пытаюсь даже вручную вызывать модуль в начале выполнения этой же программы - один результат.
Немного упрощенный код и оформленный как library (версия для подключения в Java):
............................................................................................................................
library GTU;

uses
  Windows, Messages, SysUtils, Variants, Classes, TeEngine, Series, ToolWin,
  ComCtrls,  Math, OleServer, ComObj;

procedure GTD(var INI: Integer); cdecl; external 'PD25.dll';

//функции для обмана компилятора - нужно получить адрес общего блока
function DB1(i :Integer)  :Integer; cdecl; external 'PD25.dll';

//-------------------------------------------------------------
type
  TFnCOMMON =  function (i :Integer) :Integer; cdecl;

{--------------------------------------------}
function GetAdrCOMMON(fn :TFnCOMMON) : Pointer;
var
  Pn1,Pn2,pn3 : Pointer;
begin
  Pn1 := Addr(fn);
  Pn2 := Pointer(Pointer(Integer(Pn1) + 2)^);
  Pn3 := Pointer(Pn2^);
  result := Pn3;
end;

{--------------------------------------------}
type

T_ADBL = ARRAY [1..1000] of  Double;
TP_ADBL = ^T_ADBL;
T_AINT = ARRAY [1..1000] of  Integer;
TP_AINT = ^T_AINT;
PDouble = ^Double;
PInt = ^Integer;
{-----------------------------------------------}

var
   PDB1: ^T_ADBL;

{$R *.res}

procedure loadAdressGTU();
begin
  PDB1 := GetAdrCOMMON(DB1);
end;

procedure setStep(value:Double); stdcall;
begin
   PDB1^[2] := value;
end;

procedure setFuel(value:Double); stdcall;
begin
   PDB1^[3] := value;
end;

procedure setPowerLoad(value:Double); stdcall;
begin
   PDB1^[27] := value;
end;

procedure initialize(); stdcall;
var INI : Integer;
begin
   loadAdressGTU();
   INI := 0;
   GTD(INI);
end;

procedure calculateIteration(); stdcall;
var INI : Integer;
begin
   INI := 1;
   GTD(INI);
end;

Function getFuel():Double;stdcall;
begin
   Result:=PDB1^[3];
end;

function getPowerLoad():Double; stdcall;
begin
   Result := PDB1^[27];
end;

function getFreeTurbinePower():Double; stdcall;
begin
   Result := PDB1^[28];
end;

function getFreeTurbineSpeed():Double; stdcall;
begin
   Result := PDB1^[9];
end;

function getTurbochargerSpeed():Double; stdcall;
begin
   Result := PDB1^[10];
end;

function getTurbochargerOutPressure():Double; stdcall;
begin
   Result := PDB1^[31];
end;

function getFreeTurbineGasTemperature():Double; stdcall;
begin
   Result := PDB1^[37];
end;

function getGasTemperature():Double; stdcall;
begin
   Result := PDB1^[45];
end;

function getInpitAirTemperature():Double; stdcall;
begin
   Result := PDB1^[63];
end;

exports setStep, setFuel, setPowerLoad, initialize, calculateIteration,
        getFuel, getPowerLoad, getFreeTurbinePower,
        getFreeTurbineSpeed, getTurbochargerSpeed, getTurbochargerOutPressure,
        getFreeTurbineGasTemperature, getGasTemperature, getInpitAirTemperature;

end.
............................................................................................................................

Вызывается initialize(); - и выдает ошибку.
При этом если вызвать просто loadAdressGTU(), то после этого процедуры set/get работают - это по сути обращение к common блокам.
Интерфейс программы на фортране:
............................................................................................................................
SUBROUTINE GTD(INI)
IMPLICIT NONE
cDEC$ ATTRIBUTES DLLEXPORT::GTD
cDEC$ ATTRIBUTES DLLEXPORT:: /DB1/
INTEGER :: INI

COMMON/DB1/ A  
REAL*8, DIMENSION(200) :: A
............................................................................................................................
Как исправить, подскажите пожалуйста?

Автор: V0LT 27.10.2014, 12:34
IDA в помощь ... ну и без фортрановской DLL совсем не понятно куда копать

Этот ответ добавлен с нового Винграда - http://ru.vingrad.com/vyzov-Fortran-iz-Delphi-id544b5b52ae20154c758b4567#findElement_E7045_544e1196ae2015235ee4c8ce_0

Автор: OK54 27.10.2014, 14:05
> IDA в помощь
100% фортран кода смогу декомпилировать? Или пипец запарюсь?

>  ну и без фортрановской DLL совсем не понятно куда копать
что еще кроме приведенного интерфейса PROGRAM PD25 нужно? Саму dll?

Автор: V0LT 27.10.2014, 15:05
Как минимум

Этот ответ добавлен с нового Винграда - http://ru.vingrad.com/vyzov-Fortran-iz-Delphi-id544b5b52ae20154c758b4567#findElement_E7045_544e34f7ae2015e67ae4c5a7_0

Автор: OK54 27.10.2014, 17:45
положил архив. dll обращается к файлу GTD1.d при вызове метода initialize.

Автор: OK54 28.10.2014, 14:24
ошибку совершил в описании интерфейса фортран программы, исправил в первом сообщении.

Автор: drkot 14.11.2014, 02:35
1) Метод - Пошаговая отладка
2) Причина - не  (правильно) инициализирован указатель

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)