fortran66のブログ

fortran について書きます。

iphlpapi という Win32 API を呼び出すことで Fortran でもネットワーク関連のプログラムが可能になります。しかし Intel は iphlpapi.lib 用のヘッダー・モジュールを用意してくれていないので、自分で定義を探して定数などを定義する必要があります。基本的にはC用のヘッダーファイルをみて、Fortran 用のインターフェースを作ります。

ここでライブラリーとして iphlpapi.lib を、明示的にリンクしておく必要があります。


以下に自分のパソコンのネットワークカードの物理アドレス(または MAC ADDRESS)を表示させるプログラムを示します。ほとんどは定数やインターフェースの定義になります。



出力例

この結果は、コンソールから ipconfig/all と打つことで確かめられます。





追記:以下のプログラムの最後の出力ループで、変数 i となるべき所が整数 1 となっていたので訂正します。FORMAT 等を整えた修正版に差し替えておきます。

PROGRAM MAC   
USE ifwinty   
IMPLICIT NONE   
!   
INTEGER, PARAMETER :: MAX_ADAPTER_DESCRIPTION_LENGTH = 128 !// arb.   
INTEGER, PARAMETER :: MAX_ADAPTER_NAME_LENGTH        = 256 !// arb.   
INTEGER, PARAMETER :: MAX_ADAPTER_ADDRESS_LENGTH     =   8 !// arb.   
!   
TYPE :: t_IP_ADDRESS_STRING   
 SEQUENCE 
 CHARACTER (4) :: String(4)   
END TYPE   
TYPE :: t_IP_MASK_STRING   
 SEQUENCE 
 CHARACTER (4) :: String(4)   
END TYPE   
!   
TYPE :: t_IP_ADDR_STRING   
 SEQUENCE 
 INTEGER (LPLONG)           :: pNext   
 TYPE (t_IP_ADDRESS_STRING) :: IpAddress   
 TYPE (t_IP_MASK_STRING)    :: IpMask   
 INTEGER (DWORD)            :: Context   
END TYPE   
!   
TYPE :: t_IP_ADAPTER_INFO   
 SEQUENCE 
 INTEGER (LPLONG) :: pNext    
 INTEGER (DWORD)  :: ComboIndex   
 CHARACTER (LEN = MAX_ADAPTER_NAME_LENGTH        + 4) :: AdapterName   
 CHARACTER (LEN = MAX_ADAPTER_DESCRIPTION_LENGTH + 4) :: Description   
 INTEGER (UINT)   :: AddressLength   
 INTEGER (BYTE)   :: Address(MAX_ADAPTER_ADDRESS_LENGTH)   
 INTEGER (DWORD)  :: Index   
 INTEGER (ULONG)  :: iType   
 INTEGER (ULONG)  :: DhcpEnabled   
 INTEGER (LPLONG) :: pCurrentIpAddress    
 TYPE (t_IP_ADDR_STRING) :: IpAddressList   
 TYPE (t_IP_ADDR_STRING) :: GatewayList   
 TYPE (t_IP_ADDR_STRING) :: DhcpServer   
 INTEGER (BOOL)  :: HaveWins   
 TYPE (t_IP_ADDR_STRING) :: PrimaryWinsServer   
 TYPE (t_IP_ADDR_STRING) :: SecondaryWinsServer   
 INTEGER (ULONG) :: LeaseObtained   
 INTEGER (ULONG) :: LeaseExpires   
END TYPE    
!   
INTERFACE   
 INTEGER (BOOL) FUNCTION GetAdaptersInfo(arg1, arg2)   
 USE ifwinty   
 !DEC$ ATTRIBUTES DEFAULT, STDCALL, DECORATE, ALIAS:'GetAdaptersInfo' :: GetAdaptersInfo   
 INTEGER (LPLONG) :: arg1   
 INTEGER (LPLONG) :: arg2   
 END FUNCTION   
END INTERFACE   
!   
TYPE (t_IP_ADAPTER_INFO) :: AdapterInfo(16)   
TYPE (t_IP_ADDR_STRING)  :: CurrentIpAddress   
INTEGER (DWORD) :: dwRetVal    
INTEGER (BOOL)  :: iret   
INTEGER :: i   
dwRetVal = sizeof(AdapterInfo)   
iret = GetAdaptersInfo(LOC(AdapterInfo), LOC(dwRetVal))   
IF (iret /= 0) STOP 'Error: GetAdaptersInfo'  
DO i = 1, 16   
! PRINT *, AdapterInfo(i)%pNext   
! PRINT *, AdapterInfo(i)%ComboIndex   
! PRINT *, AdapterInfo(i)%AddressLength   
 PRINT '(A)', AdapterInfo(i)%Description(1:INDEX(AdapterInfo(i)%Description(1:128), CHAR(0)))   
 PRINT '(5(Z2.2,"-"), Z2.2)', AdapterInfo(i)%Address(1:AdapterInfo(i)%AddressLength)   
 PRINT '(8A)', AdapterInfo(i)%IpAddressList%IpAddress, AdapterInfo(i)%IpAddressList%IpMask  
 IF (AdapterInfo(i)%pNext == NULL) EXIT   
END DO   
STOP   
END PROGRAM MAC  
  • ここで関数 sizeof() は、Intel Visual Fortran の固有命令で、Fortran の標準命令ではありません。構造体などのバイト数を返します。
  • C言語の文字列は終端文字として CHAR(0)*1を使っています。

*1:NULL文字