タイトルで述べたように、混合言語プログラミング、より正確には Ada から Fortran コードへの配列の取得に問題があります。私のAdaプロシージャ宣言は次のようになります。
procedure Get_Double_Array
(Double_Array : in System.Address;
Length_of_Array : in System.Address);
pragma Export(Fortran, Get_Double_Array, "Get_Double_Array_");
私のプロシージャの対応する本体は
procedure Get_Double_Array
(Double_Array : in System.Address;
Length_Of_Array : in System.Address)
is
use Interfaces.Fortran;
Array_Length : Fortran_Integer;
for Array_Length'Address use Length_Of_Array;
Result_Array : Double_Precision_Array(1..3);
for Result_Array'Address use Double_Array;
begin
Result_Array(1) := Double_Precision(1.0);
Result_Array(2) := Double_Precision(2.0);
Result_Array(3) := Double_Precision(3.0);
Array_Length := Fortran_Integer(Result_Array'Last);
end Get_Double_Array;
Double_Precision_Array の宣言は次のようになります
type Double_Precision_Array is (Fortran_Integer range <>) of Double_Precision;
pragma Convention(Fortran, Double_Precision_Array);
この手順を DLL で使用できるようにすることは、既に機能しています。作成された dll の dumpbin /exports は、期待どおりに Get_Double_Array_ を示します。
Fortran プログラムは次のようになります。
PROGRAM TPROG
IMPLICIT NONE
INTERFACE
SUBROUTINE GETARR(DPARR, LENGTH)
cDEC$ ATTRIBUTES DLLIMPORT, ALIAS : '_Get_Double_Array_' :: GETARR
DOUBLE PRECISION, DIMENSION (:) :: DPARR
INTEGER :: LENGTH
END SUBROUTINE
END INTERFACE
DOUBLE PRECISION, DIMENSION(3) :: XDOT
INTEGER :: LENGTH
CALL GETARR(XDOT, LENGTH)
END PROGRAM TPROG
fortran コードは gfortran でコンパイルされ、作成された dll に対応する lib とリンクされます。コマンドラインは
gfortran -o test.exe test.f Ada_Lib.lib
Fortran コードの Call ステートメントの前にデバッグ出力を挿入すると、Get_Double_Array プロシージャが呼び出されていることがわかりますが、例外が発生します。
raised PROGRAM_ERROR: Name_Of_The_Ada_Body.adb: misaligned address value
このメッセージの行番号は、Array_Length 変数を宣言する場所です。Ada Attribute 'Alignment については知っていますが、Fortran 互換のデータ型を既に使用しているため (少なくとも私はそう思います)、この状況での使用方法がわかりません。
Ada 側で C 規則をエクスポートし、配列宣言にも C 規則を使用し、Fortran の cDEC$ 行を 'C, DLLIMPORT, ALIAs' に適合させると、長さの値は常に正しくなりますが、配列の内容は完全に役に立たない。
配列の範囲は、デバッグ用にのみ固定されています。後で、Array は任意の長さにすることができるため、配列の長さも返す必要があります。
私が間違っていること、次に何を試すことができるかについて、役立つヒントや説明はありますか?