Fortranã¯ãé·å¹Žã«ããã£ãŠãããã°ããã³åäœããèšå€§ãªéã®ã³ãŒããèšè¿°ããŠããŸããã ãFortranãšCã®ã©ã¡ããè¯ãã§ããïŒããšãã質åãããã€ããã¯ãããŸããã åèšèªã«ã¯é·æãšçæããããŸãã ããããCèšèªãåºç¯ã«æ®åããŠããããšãèãããšãã³ãŒãã®äžéšãFortranã§èšè¿°ãããŠããïŒãããããã§ã«èšè¿°ãããŠããïŒCèšèªã®ä»ã®èšèªã§ã¯ãããã€ããªãããã¢ããªã±ãŒã·ã§ã³ã®ã±ãŒã¹ãç¹å®ã®ãµãŒã¯ã«ã§ãŸããŸãæ®åããŠããŸãããããããããã®èšèªã«ã¯ç¹å®ã®ç¹ç°æ§ããããç§ããã§ã«éšåçã«è©±ããããš ãããã³ç§ãã¡ã«ãã£ãŠæžãããã¢ããªã±ãŒã·ã§ã³ãæ£ããæ©èœããããšã«ã€ããŠãå€ãã®ãã¥ã¢ã³ã¹ãèæ ®ããå¿ èŠããããŸãã ããŒã¿åãåŒã³åºãèŠåãåœåèŠåã®éãã«ãããæ··åèšèªã¢ããªã±ãŒã·ã§ã³ãäœæããã¿ã¹ã¯ã¯ç°¡åã§ã¯ãããŸããã Fortran 2003ããCãšFortranéã®çžäºéçšæ§ã®åé¡ã解決ããããã«ç¹å¥ã«èšèšãããããŒã«ã®ã»ããå šäœãå°å ¥ããããšã¯è¯ãããšã§ãã ã¡ãªã¿ã«ãç§ã¯ãã®ãããªä»äºãæšæºåããä»ã®èšèªãèŠããŠããŸãã-Fortranã圌ã®ãåæ ã®æãå·®ã䌞ã¹ããããã«å¥ã®ããã©ã¹èšå·ã
ãã®ãªãã©éãªã©ã¯äœã§ããïŒ ãçžäºéçšæ§ããšããçšèªã¯ãFortranã³ãŒãã§é¢æ°CãåŒã³åºãå¯èœæ§ããŸãã¯ãã®éãæå³ããŸãã ããã«ãã°ããŒãã«å€æ°ã䜿çšããããCã§å¯Ÿå¿ããããŒã«ã«å€æ°ãããŒã¿æ§é ãåæã宣èšãããã§ããŸããäž»ãªèãæ¹ã¯ããã¹ãŠãCãšFortranã®äž¡æ¹ã§åãããã«æ©èœããããšã§ãã Cã¯æšæºC99ïŒISO / IEC 9899ïŒ1999ïŒãæå³ããããšã«æ³šæããŠãã ããã ãšããã§ãFortranã³ã³ãã€ã©ã®ç¹å®ã®å®è£ ã«ã¯ãã©ã®Cã³ã³ãã€ã©ããã¬ã³ãã«ããããéžæããæš©å©ããããŸãã Intel Fortanã®å ŽåãWindowsã§ã¯Microsoft Visual C ++ãLinuxããã³OS Xã§ã¯gccã§ããIntelC ++ã¯ã©ãã§ããïŒ Visual C ++ããã³gccãšäºææ§ããããããåé¡ã¯ãããŸããïŒããã¯äºæ³ãããããšã§ãïŒã
Fortranã¯ã次ã®æ¹æ³ã§åãçžäºéçšæ§ã®ãµããŒããå®è£ ããŸãã
- çžäºéçšå¯èœãªããŒã¿åã®å¶é
- BINDæ§ç¯ïŒCïŒ
- ISO_C_BINDINGã¢ãžã¥ãŒã«
- å±æ§å€
ãæ··åãã¢ããªã±ãŒã·ã§ã³ãéçºããéã®äž»ãªå°é£ã®1ã€ã¯ãCãšFortranã®åãç°ãªãããšã§ãããã€ã³ã¿ãŒã®æŠå¿µãæååã®æäœãé¢æ°ãžã®ãã€ã³ã¿ãŒãªã©ã§ãã ãããŠãåºæ¬çãªã¿ã€ãã§ã¯ããã»ã©åçŽã§ã¯ãããŸããã Cã«ã¯short intããlong long intãŸã§ã®åããããšããŸãããã Fortranã«ã¯é¡äŒŒç©ãããå Žåãšãªãå ŽåããããŸãã
ãã®ãã¹ãŠãããŸãæ©èœãããããã«ããããã®èšèªã®ãåæ ããæ åœããã¢ãžã¥ãŒã«ISO_C_BINDINGãFortranã«è¿œå ãããŸããã äœããããŸããïŒ Fortranã®ããŒã¿åãCã³ãŒãã§ã®äœæ¥ã«å¯ŸããŠãæ£ãããããšã確èªã§ããããŒã«ã®ã»ããã
ããšãã°ã intåã®å ŽåãFortranã§INTEGERåïŒC_INTïŒã䜿çšã§ãã C_INTã¯ISO_C_BINDINGã¢ãžã¥ãŒã«ã§å®çŸ©ãããŸãã ã€ã³ãã«Fortranã®å ŽåãINTEGERã¯4ãã€ãé·ã§ãããä»ã®å®è£ ã§ã¯äºå®ã§ã¯ãããŸããã ååä»ãå®æ°ã䜿çšãããšã移æ€æ§ãä¿èšŒãããŸãã
Fortranã¢ããªã±ãŒã·ã§ã³ã§äœ¿çšã§ããCãªããžã§ã¯ãã¯æ¬¡ã®ãšããã§ãã
- æ°å€åïŒæŽæ°ãæµ®åå°æ°ç¹ãè€çŽ æ°
- è«çåïŒFortranã«ã¯LOGICALåããããŸãïŒ
- è¡
- æ§é
- ãã€ã³ã¿
- é å
- ã°ããŒãã«å€æ°
- æ©èœ
åæã«ãFortranåã¯å€ããŸãŸã§ãããçžäºéçšå¯èœãªãã©ã¡ãŒã¿ãŒKINDãšã¢ãžã¥ãŒã«ã®å®æ°ã䜿çšããŠå€æŽããŸãã ããã¯ãã¿ã€ãCãšFortranéã®äžçš®ã®ããªã³ã¯ããšããŠæ©èœããŸãã ã¿ã€ãéã®å¯Ÿå¿ã¯ã次ã®è¡šã«èšèŒãããŠããŸãã
Fortranã¿ã€ã | KINDãã©ã¡ãŒã¿ãŒ | ã¿ã€ãC |
---|---|---|
æŽæ° | C_int | int
眲åãããint |
C_SHORT | çæŽæ°
眲åãããçæŽæ° | |
C_LONG | é·æŽæ°å
笊å·ä»ãlong int | |
C_LONG_LONG | long long int
眲åãããlong long int | |
C_SIGNED_CHAR | 眲åãããæå
笊å·ãªãæå | |
C_SIZE_T | size_t
| |
å® | C_FLOAT | æµ®ã |
C_DOUBLE | ããã« | |
C_LONG_DOUBLE | ãã³ã°ããã« | |
è€é㪠| C_COMPLEX | _Complex |
C_DOUBLE_COMPLEX | double _Complex | |
C_LONG_DOUBLE_COMPLEX | long double _Complex | |
ããžã«ã« | C_BOOL | _Bool |
ãã£ãŒã¿ãŒ
| C_char | ãã£ãŒ |
ãã1ã€ã®æ©èœã¯ãCããã³Fortranã§ã¯ããŒã«åãtrue / falseã«èšå®ãããããšã§ãã
Cãfalseã«0ã䜿çšããtrueã«0以å€ã®æ°å€ã䜿çšããå ŽåãFortranã§ã¯å¶æ°ã¯falseã§ãå¥æ°ã¯trueã§ãã
Cã®ããã«ã«ãŒã«ãå€æŽãã-fpscomp logicalsãªãã·ã§ã³ïŒ/ fpscompïŒWindowsã®logicalsïŒã䜿çšããããšãå¿ããªãã§ãã ããã
ã¡ãªã¿ã«ã-standard-semanticsãªãã·ã§ã³ïŒWindowsã®å Žåã¯/ standard-semanticsïŒã䜿çšãããšãæé»çã«æ¥ç¶ãããŸããFortran2003æšæºã䜿çšããå Žåã¯éåžžã«æšå¥šããããªãã·ã§ã³ã§ãã
次ã«ãäŸã§ãã¹ãŠãã©ã®ããã«æ©èœããããèŠãŠã¿ãŸãããã Fortranã§æžãå Žå
INTEGER(KIND=C_LONG) :: I
KIND = C_LONGã䜿çšããããšã«ãããå€æ°ãCã³ãŒãã§äœ¿çšããããšãã«åã«åé¡ãçºçããªãããšãä¿èšŒããã ããã§å€æ°ã¯ long intåïŒããŒã ãã¬ãŒãã«ããïŒã«ãªããŸãã çµã¿èŸŒã¿åã䜿çšãããšããã¹ãŠãã·ã³ãã«ã«ãªããŸãããã¬ãŒãå ã®KINDãšåžœåå ã®ç©ã«é©ããå®æ°ãæ¢ããŠããŸãã ãšããã§ããã®æ©èœã¯ãã¹ãŠã¢ãžã¥ãŒã«ãšããŠå©çšã§ããããã USEããŒã¯ãŒãã䜿çšããŠæ¥ç¶ããå¿ èŠããããŸãã
USE, INTRINSIC :: ISO_C_BINDING
ãããã£ãŠãã¢ãžã¥ãŒã«ã®åã®ãã¹ãŠã®å®æ°ã䜿çšå¯èœã«ãªããŸãã åå空éãè©°ãŸãããªãããã«ãããšãã°æ¬¡ã®ããã«ãå®éã«äœ¿çšããã¿ã€ãã®ã¿ã«ã¹ã³ãŒããå¶éããããšããå§ãããŸãã
USE, INTRINSIC :: ISO_C_BINDING, ONLY C_LONG
åèªäœã®ä»ã«ã察å¿ããååããªããžã§ã¯ãCã§ããããšãFortranã³ã³ãã€ã©ãŒã«äŒããBINDã³ã³ã¹ãã©ã¯ãïŒã¢ãžã¥ãŒã«ã®äžéšã§ã¯ãªããFortran 2003æšæºã®äžéšïŒããããŸããããã«ãããã¯æ瀺çããã³æé»çã«å®è¡ã§ããŸãã ããšãã°ãCã«ã¯ãã®ãããªã°ããŒãã«å€æ°ããããŸãã
int a_int; long b_long;
ãããŠãFortranã³ãŒããããšãã°ã¢ãžã¥ãŒã«ã§ããããæ£ãã䜿çšãããã®ã§ãã
MODULE TEST_BINDING USE ISO_C_BINDING ! binding A_INT a_int INTEGER(C_INT), BIND(C) :: A_INT ! binding B b_long INTEGER(C_LONG) :: B BIND(C, NAME=' b_long ') :: B END MODULE TEST_BINDING
ãã®ãããªãæãã¯ãªããžã§ã¯ãã«å¿ èŠã§ãã ãã®äŸã§ã¯ãCã§äœæãããåãã°ããŒãã«å€æ°ã䜿çšããŠFortranã³ãŒãã§äœæ¥ã§ããŸããããšãã°ãäœããã®æ©èœãããå Žåã
Cfunc(float a1, double a2);
次ã«ããã®ãããªããŒã¿ãåŒæ°ãšããŠäœ¿çšã§ããŸããBINDãå®è¡ããå¿ èŠã¯ãããŸããã
REAL(C_FLOAT) :: A1 COMPLEX(C_DOUBLE) :: A2
FortranãšCã®åé¡ã®1ã€ã¯ãæååãæäœãããšãã®éãã§ããã ãããã£ãŠããã®ãããªé¢æ°ã«æååãæž¡ãããšãã§ããããã«ããã«ã¯ïŒ
void copy(char in[], char out[]);
KIND = C_CHARããã³è¡çµäºæåC_NULL_CHAR ïŒFortranã®ã¢ããã°\ 0 ïŒã䜿çšããå¿ èŠããããŸãã
CHARACTER(LEN=10, KIND=C_CHAR) :: DIGIT_STRING = C_CHAR '123456789' // C_NULL_CHAR CHARACTER(KIND=C_CHAR) :: DIGIT_ARR(10)
ãŸããFortranã®è£œåã©ã€ã³ã¯ãCãšã®ãåã ã¡ãã«ãªããŸããé¢æ°ã«å®å šã«æž¡ãããšãã§ããŸãã
ãã ããé¢æ°ã¯Cã®å¯Ÿå¿ããé¢æ°ãšäœããã®æ¹æ³ã§æ¥ç¶ããå¿ èŠããããŸããããã¯ãFortranã§ã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšããŠè¡ãããŸãã
INTERFACE SUBROUTINE COPY(IN, OUT), BIND(C) USE ISO_C_BINDING CHAR(KIND=C_CHAR), DIMENSION(*) :: IN, OUT END SUBROUTINE COPY END INTERFACE
ãããŠä»ãç§ãã¡ã¯å®å šã«æžãããšãã§ããŸã
CALL COPY(DIGIT_STRING, DIGIT_ARR)
æãèå³æ·±ãã®ã¯ããã€ã³ã¿ãŒãæäœããããšã§ãã åŒæ°ãšããŠãã€ã³ã¿ãŒãæã€é¢æ°ã®å Žå
short func(double *a; int *b; int c[10]; void *d)
Fortranã§ã¯æ¬¡ã®å€æ°ã䜿çšã§ããŸãã
REAL(C_DOUBLE) :: A ! A *, INTEGER(C_INT) :: B, V(10) ! B *b c[] TYPE(C_PTR), VALUE :: D !D *d, void*
ãã€ã³ã¿ãŒã®KINDãã©ã¡ãŒã¿ãŒããããšããäºå®ã«å ããŠãããšãã°ãããã«ããã€ã³ã¿ãŒC_NULL_PTR -Cããã®ãã«ã®é¡äŒŒç©ãªã©ãããã€ãã®è¿œå æ©èœããããŸããç¹å¥ãªé¢æ°ããããŸãã
C_F_POINTERã¯ãFortranãã€ã³ã¿ãŒããªããžã§ã¯ãCã«é¢é£ä»ããŸãããã®é¢æ°ã®æ§æã¯æ¬¡ã®ãšããã§ãã
CALL C_F_POINTER( CPTR, FPTR [,SHAPE] ) TYPE(C_PTR), INTENT(IN) :: CPTR <type_spec>, POINTER, INTENT(OUT) :: FPTR INTEGER, INTENT(IN), OPTIONAL :: SHAPE
CPTRãžã®å ¥ååŒæ°ãšããŠãCã®ãªããžã§ã¯ããžã®ãã€ã³ã¿ãŒãæž¡ããŸã;åºåã«ã¯ããã®ãªããžã§ã¯ããžã®Fortranãã€ã³ã¿ãŒFPTRããããŸãã
C_LOCã¯ããªããžã§ã¯ãCãŸãã¯Fortranã®ã¢ãã¬ã¹ãè¿ããŸãã
C_ADDRESS = C_LOC(OBJECT)
C_ASSOCIATEDã¯ããã€ã³ã¿ãŒãnullãã©ãããããã³ãªããžã§ã¯ãCã«é¢é£ä»ããããŠãããã©ããã確èªããŸãã
掟çåãèã«ãããŸããã§ããã ããšãã°ããã®ãããªctypeæ§é
typedef struct { int a, b; float c; } ctype;
ã¿ã€ãFTYPEã§åäœããŸãïŒ
TYPE, BIND(C) :: FTYPE INTEGER(C_INT) :: A, B REAL(C_FLOAT) :: C END TYPE FTYPE
ãã¡ãããæçš¿ã®ãã¬ãŒã ã¯ãŒã¯å ã§æšæºã®è©³çŽ°ããã¹ãŠè©³çŽ°ã«èª¬æããããšã¯ã§ããŸãããããã®ç®æšãèšå®ããŸããã§ãããããã®å šäœãã©ã®ããã«æ©èœãããã«ã€ããŠæããã«ããŸãã ããŠãçŸå®ã«è¿ãæåŸã®äŸã¯ã ISO_C_BINDINGã¢ãžã¥ãŒã«ã䜿çšããŠFortranãšCã®äž¡æ¹ããé¢æ°ãåŒã³åºãæ¹æ³ã瀺ããŠããŸãã
Cé¢æ°ãåŒã³åºãFortranã®äŸããå§ããŸãããã
int C_Library_Function(void* sendbuf, int sendcount, int *recvcounts);
ãããã£ãŠãå¿ èŠãªKINDãã©ã¡ãŒã¿ãŒã䜿çšããŠã€ã³ã¿ãŒãã§ãŒã¹ãäœæããŸãã
MODULE FTN_C_2 INTERFACE INTEGER (C_INT) FUNCTION C_LIBRARY_FUNCTION (SENDBUF, SENDCOUNT, RECVCOUNTS) BIND(C, NAME='C_LIBRARY_FUNCTION') USE, INTRINSIC :: ISO_C_BINDING IMPLICIT NONE TYPE (C_PTR), VALUE :: SENDBUF INTEGER (C_INT), VALUE :: SENDCOUNT TYPE (C_PTR), VALUE :: RECVCOUNTS END FUNCTION C_LIBRARY_FUNCTION END INTERFACE END MODULE FTN_C_2
ãããŠä»ãé¢æ°åŒã³åºããçŽæ¥ïŒ
USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_INT, C_FLOAT, C_LOC USE FTN_C_2 ... REAL (C_FLOAT), TARGET :: SEND(100) INTEGER (C_INT) :: SENDCOUNT INTEGER (C_INT), ALLOCATABLE, TARGET :: RECVCOUNTS(100) ... ALLOCATE( RECVCOUNTS(100) ) ... CALL C_LIBRARY_FUNCTION(C_LOC(SEND), SENDCOUNT, C_LOC(RECVCOUNTS)) ...
ãŸããååãŸãã¯ããŒã¿åã®ãããã«ãåé¡ã¯ãããŸããã
éã«ãFortrané¢æ°ãåŒã³åºãã¿ã¹ã¯ïŒéåžžã«äžè¬çãªã¿ã¹ã¯ïŒãããå Žåããã®ã¢ãžã¥ãŒã«ã¯åé¡ã®è§£æ±ºã«ã圹ç«ã¡ãŸãã ã·ãã¥ã¬ãŒã·ã§ã³æ©èœãããå ŽåïŒ
SUBROUTINE SIMULATION(ALPHA, BETA, GAMMA, DELTA, ARRAYS) BIND(C) USE, INTRINSIC :: ISO_C_BINDING IMPLICIT NONE INTEGER (C_LONG), VALUE :: ALPHA REAL (C_DOUBLE), INTENT(INOUT) :: BETA INTEGER (C_LONG), INTENT(OUT) :: GAMMA REAL (C_DOUBLE),DIMENSION(*),INTENT(IN) :: DELTA TYPE, BIND(C) :: PASS INTEGER (C_INT) :: LENC, LENF TYPE (C_PTR) :: C, F END TYPE PASS TYPE (PASS), INTENT(INOUT) :: ARRAYS REAL (C_FLOAT), ALLOCATABLE, TARGET, SAVE :: ETA(:) REAL (C_FLOAT), POINTER :: C_ARRAY(:) ... ! C_ARRAY , C CALL C_F_POINTER (ARRAYS%C, C_ARRAY, (/ARRAYS%LENC/) ) ... ! ARRAYS%LENF = 100 ALLOCATE (ETA(ARRAYS%LENF)) ARRAYS%F = C_LOC(ETA) ... END SUBROUTINE SIMULATION
Cã§æ§é ã宣èšããŸãã
struct pass {int lenc, lenf; float *c, *f;};
ãããŠæ©èœïŒ
void simulation(long alpha, double *beta, long *gamma, double delta[], struct pass *arrays);
ãããŠãå®å šã«åœŒå¥³ã«é»è©±ããããšãã§ããŸãïŒ
simulation(alpha, &beta, &gamma, delta, &arrays);
以äžã§ãã æ°ããæšæºã®ãã®æ©èœã䜿çšãããšãå€ãã®éçºè ãå€æ°ã®åé¡ãåé¿ã§ããããã«ãªããFortranãšCã¯ãããŸã§ä»¥äžã«äœ¿ãããããªããšæããŸãã