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

win32 stdcall - where to place ATTRIBUTES ?

MikeWinsteps
Novice
298 Views

Folks, another problem converting Windows Win32 code to 64-bit IFORT Fortran. Any suggestions ?

 

Error message shown for Main line:

Attributes conflict with USE (ABOUTDLGPROC)

 

Main line:

integer*8 rstd8
integer*8 g_hInstance, ZERO8
.....
rstd8 = DialogBoxParam_G1 (g_hInstance,"IDD_ABOUT"C, ZERO8, LOC(ABOUTDLGPROC), 0 )
!DEC$ ATTRIBUTES STDCALL :: ABOUTDLGPROC
....

 

Here is the win32 call-back routine:

 

logical function ABOUTDLGPROC (hDlg, message, wParam, lParam)
!DEC$ ATTRIBUTES STDCALL :: ABOUTDLGPROC

integer(HANDLE_SIZE),value :: hDlg ! window handle
integer, value :: message ! message to process
integer,value :: wParam ! WPARAM of message
integer(HANDLE_SIZE),value :: lParam ! LPARAM of message

..................

end

 

and here is the IFORT-generated interface that is USEd for the Main line compilation:

 

MODULE ABOUTDLGPROC__genmod
INTERFACE
FUNCTION ABOUTDLGPROC(HDLG,MESSAGE,WPARAM,LPARAM)
INTEGER(KIND=8) ,VALUE :: HDLG
INTEGER(KIND=4) ,VALUE :: MESSAGE
INTEGER(KIND=4) ,VALUE :: WPARAM
INTEGER(KIND=8) ,VALUE :: LPARAM
LOGICAL(KIND=4) :: ABOUTDLGPROC
END FUNCTION ABOUTDLGPROC
END INTERFACE
END MODULE ABOUTDLGPROC__genmod

 

What is wrong??

0 Kudos
2 Replies
jimdempseyatthecove
Black Belt
275 Views

Auto-generated interfaces occur (when requested by option or by default), are generated for procedures that do not have an explicit interface.  These are Fortran <=> Fortran interfaces. A module contained procedure has an explicit interface. For external procedures you (or someone provides) an external procedure interface within the data portion of a module (e.g. the Intel provided kernel32.mod/kerenel32.f90). The callback routine is called by the Windows code. So your procedure needs to use the calling interface required by Windows.

The attribute is not placed at the point of the CALL (or statement with function).

You need to explicitly provide the interface. Inside a module (used by the procedure containing rstd8 = DialogBoxParam_G1(...)), insert

interface
  logical function ABOUTDLGPROC (hDlg, message, wParam, lParam)
  !DEC$ ATTRIBUTES STDCALL :: ABOUTDLGPROC
    integer(HANDLE_SIZE),value :: hDlg ! window handle
    integer, value :: message ! message to process
    integer,value :: wParam ! WPARAM of message
    integer(HANDLE_SIZE),value :: lParam ! LPARAM of message
  end function ABOUTDLGPROC
end interface

Jim Dempsey

 

 

0 Kudos
Steve_Lionel
Black Belt
268 Views

There are multiple problems here. First of all, the AboutDialogProc should not return a LOGICAL type. Microsoft describes this as INT_PTR which is a pointer-sized integer. It wants the procedure to return the named constants TRUE or FALSE (from IFWINTY), which are not the same as .TRUE. and .FALSE. (unless you have /fpscomp:logicals or /standard-semantics enabled.)  The kinds of the arguments are wrong here, and the VALUE attribute in Jim's suggested code doesn't do anything here because of the STDCALL attribute. (It would if BIND(C) was used.)

I suggest instead:

interface
  function ABOUTDLGPROC (HDLG, MESSAGE, WPARAM, LPARAM) BIND(C)
  import
  !DEC$ ATTRIBUTES STDCALL :: ABOUTDLGPROC
  INTEGER(INT_PTR) :: ABOUTDLGPROC
  INTEGER(HWNT), VALUE :: HDLG
  INTEGER(UINT), VALUE :: MESSAGE
  INTEGER(fWPARAM), VALUE :: WPARAM
  INTEGER(fLPARAM), VALUE :: LPARAM
  end function ABOUTDLGPROC
end interface

Of course, the actual procedure needs to have the same interface. Much better is to put it in a module and just USE the module to pick up the procedure.

0 Kudos
Reply