Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29277 Discussions

equivalent data types between Fortran and C

forall
Beginner
1,466 Views
When using IFWIN routines in conjunction with MSDN documentation, it is necessary to call what appear to be wrappers of C++ functions with fortran arguments.

For example,

[cpp]C++

BOOL WINAPI ReadProcessMemory(
  __in   HANDLE hProcess,
  __in   LPCVOID lpBaseAddress,
  __out  LPVOID lpBuffer,
  __in   SIZE_T nSize,
  __out  SIZE_T *lpNumberOfBytesRead
);

[/cpp]

Trying to get the correct arguments, I used LOGICAL(1) to store the BOOL (treating .true. as 1, .false. as 0), INT_PTR_KIND for pretty much everything else (HANDLE, LPCVOID, SIZE_T, etc). In another case I also used INTEGER(1) to store a BYTE variable - though I also recalled reading somewhere thar CHARACTER(1) is the Fortran equivalent of BYTE (?).

Is this correct? Using these correspondences seems to work, but I am not sure if it works for the right reasons and is reliable, or just works due to some fluke.. For example, I noticed that SIZEOF(.true.)=4, which somehow doesnt seem consistent with the 0/1 values of BOOL (does it not imply lots of wasted storage for LOGICAL arrays?).

Comments/advice appreciated as usual.
0 Kudos
2 Replies
joerg_kuthe
Novice
1,466 Views
A comment at first. Intel supplies an INTERFACE to ReadProcessMemory:

INTERFACE
FUNCTION ReadProcessMemory( hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead)
use ifwinty
integer(BOOL) :: ReadProcessMemory ! BOOL
!DEC$ ATTRIBUTES DEFAULT, STDCALL, DECORATE, ALIAS:'ReadProcessMemory' :: ReadProcessMemory
integer(HANDLE) hProcess ! HANDLE hProcess
integer(LPCVOID) lpBaseAddress ! LPCVOID lpBaseAddress
integer(LPVOID) lpBuffer ! LPVOID lpBuffer
integer(DWORD) nSize ! DWORD nSize
integer(LPDWORD) lpNumberOfBytesRead ! LPDWORD lpNumberOfBytesRead
END FUNCTION
END INTERFACE

Simply use the module KERNEL32 (or IFWIN to include some more than just KERNEL32) in your Fortran program:
USE KERNEL32

According to WINAPI BOOL is defined as:
typedef int BOOL;
Intel translates that into a 4 byte INTEGER.

Regarding the use of either CHARACTER(1) or INTEGER(1) to store a byte value, I would recommend to use the one which is most useful, and so dependent of what the byte value contains. In memory both occupy 8 bits and it is just a question of interpretation of what they should mean.

By default, a logical constant (.TRUE., .FALSE.) occupies 4 bytes. Appending a KIND value allows you to reduce the memory size of the constant:
.TRUE._1
just needs one byte of storage.

Similar you can declare logical arrays using the smallest KIND value:
LOGICAL(KIND=1) :: lArr(1000)

Kind regards,

Joerg Kuthe
www.qtsoftware.de

0 Kudos
Steven_L_Intel1
Employee
1,466 Views
Do not use LOGICAL when calling C. LOGICAL has no relation to C's BOOL.

Intrinsic module ISO_C_BINDING defines the appropriate KINDs for many common C types, but if you're looking at Win32 APIs, the IFWINTY module defines KIND constants for nearly all of the appropriate types. As suggested, look at the interface block for the routine in question.
0 Kudos
Reply