Developer Guide and Reference

ID 767251
Date 10/31/2024
Public
Document Table of Contents

Call Windows API Routines

This topic describes general information about calling Windows API routines from Intel® Fortran Compiler applications. It contains the following information:

Call Windows API Routines Using the Intel® Fortran Compiler Interface Definitions

To call the appropriate Windows API routine after including the Intel® Fortran Compiler interface definitions, follow these guidelines:

  1. Examine the documentation for the appropriate routine in the Windows API (for example, GetSystemTime) to obtain the following information:

    • The number and order of arguments. You will need to declare and initialize each argument variable using the correct data type. In the case of the GetSystemTime routine, a structure (derived type) is passed by reference.

      If character arguments are present, add a null character as a terminator to the character variable before calling the Windows API routine.

    • Whether the routine returns a result (function) or not (subroutine). For example, because the GetSystemTime routine calling format starts with VOID, this routine should be called as a subroutine with a CALL statement.

  2. If you are not sure about the data type of arguments or its function return value, you can examine the interface definitions in the appropriate .F90 file in ...\INCLUDE\. For example, to view the interface definition for GetSystemTime:

    • In a text editor, open the file kernel32.f90 from ...\INCLUDE\.

    • Search for the routine name (such as GetSystemTime)

    • View the interface definition and compare it to the description in the Windows API documentation to see how the arguments are represented in Fortran. Take note of how arguments are passed; in some cases, such as when an arbitrary data type is passed by address, you must pass the address of a variable using the LOC intrinsic rather than the variable directly.

  3. If one of the arguments is a structure, look up the definition in IFWINTY.F90 in ...\INCLUDE\. For example, to view the data type definition for the T_SYSTEMTIME type used in GetSystemTime:

    • In a text editor, open the file IFWINTY.F90 from ...\INCLUDE\.

    • Search for the data type name (such as T_SYSTEMTIME).

    • View the data type definition and note the field names. In some cases, these will differ slightly from those listed in the Windows API documentation.

    • Define a variable name to use the derived-type definition in your program, such as:

      TYPE (T_SYSTEMTIME) MYTIME
  4. Many Windows API routines have an argument or return a value described as a handle. This is generally an address-sized integer and must be declared using an appropriate KIND value, typically HANDLE, which automatically provides the correct value for 32- and 64-bit platforms. For example:

    Integer(HANDLE) :: hwnd

Use the variable definition to call the Win32 routine. For example, the completed program follows:

! Getsystime.f90 file shows how to call a Windows API routine
! Since the only routine called is GetSystemTime, only include
! interface definitions from kernel32.mod instead of all modules
! included by ifwin.f90. Type definitions are defined in IFWINTY,
! which is used within KERNEL32.
!
PROGRAM Getsystime
USE KERNEL32
TYPE (T_SYSTEMTIME) MYTIME
CALL GetSystemTime(MYTIME)
WRITE (*,*) 'Current UTC time year :: ', Mytime.wYear, &
  ' Month :: ', Mytime.wMonth, ' Day :: ', Mytime.wDay, &
  ' Hour :: ', Mytime.wHour, ' Minute :: ', Mytime.wMinute, &
  ' Second :: ', Mytime.wSecond
END PROGRAM

You can create a new Fortran Console (or QuickWin) application project, add the code shown above as a source file, build it, and view the result.

Data Type Differences

Module IFWINTY, which is used by IFWIN and the other Win32 API modules, defines a set of constants for INTEGER and REAL kinds that correspond to many of the type definitions provided in the Windows WINDOWS.H header file. Use these kind values in INTEGER and REAL declarations. The following table gives the correspondence of some of the more common Windows types:

Windows Data Type

Equivalent Fortran Data Type

BOOL, BOOLEAN

INTEGER(BOOL)

BYTE

INTEGER(BYTE)

CHAR, CCHAR, UCHAR

CHARACTER or INTEGER(UCHAR)

DWORD

INTEGER(DWORD)

ULONG

INTEGER(ULONG)

SHORT

INTEGER(SHORT)

LPHANDLE

INTEGER(LPHANDLE)

PLONG

INTEGER(PLONG)

DOUBLE

REAL(DOUBLE)

Use the kind constants instead of explicitly specifying the kind as a number, or assuming a default kind.

Note that the Windows BOOL type is not equivalent to Fortran LOGICAL and should not be used with Fortran LOGICAL operators and literal constants. Use the constants TRUE and FALSE, defined in IFWINTY, rather than the Fortran literals .TRUE. and .FALSE., and do not test BOOL values using LOGICAL expressions.

Additional notes about equivalent data types for arguments:

  • If an argument is described in the Windows API documentation as a pointer, then the corresponding Fortran interface definition of that argument would have the REFERENCE property (see the ATTRIBUTES). Older interface definitions use the POINTER - Integer and pass the address of the argument, or the LOC intrinsic function.

  • Pointer arguments on systems using Intel® 64 architecture are 64 bits (8 bytes) in length.

  • Be aware that Fortran character variables need to be null-terminated. You can do this by using the C string extension (see C Strings in Character Constants):

    forstring = 'This is a null-terminated string.'C

    You can also concatenate a null using the C_NULL_CHAR constant from intrinsic module ISO_C_BINDING, or CHAR(0):

    use, intrinsic :: ISO_C_BINDING
    …
    forstring = 'This is a null-terminated string'//C_NULL_CHAR
    forstring2 = 'This is another null-terminated string'//CHAR(0)

The structures in WINDOWS.H have been converted to derived types in IFWINTY. Unions in structures are converted to union/maps within the derived type.

Names of components are generally unchanged. C bitfields do not translate directly to Fortran; collections of bitfields are declared as Fortran INTEGER types and individual bitfields are noted as comments in the source (IFWINTY.F90). To see how a particular Windows declaration was translated to Fortran, read the corresponding declaration in the appropriate .F90 source file in the Include folder.