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文字