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

Fortran interface for Raw Input Windows functions

R_K
Beginner
808 Views

I am attempting to create Fortran interfaces for windows raw input functions that are missing in the supplied user32.f90. However, can not make GetRawInputDeviceList work. Checked out many different options but always get error ERROR_INVALID_PARAMETER. Here one of the tested interfaces:

 

MODULE RawInputStructures
USE ifwinty

TYPE, PUBLIC:: RAWINPUTDEVICELIST
SEQUENCE

INTEGER(HANDLE):: hDevice
INTEGER(DWORD):: dwType

END TYPE RAWINPUTDEVICELIST

END MODULE RawInputStructures

 

MODULE RawInputFunctions
USE ifwinty

INTERFACE
FUNCTION GetRawInputDeviceList(pRawInputDeviceList, puiNumDevices, cbSize)
USE ifwinty
USE RawInputStructures

INTEGER(UINT):: GetRawInputDeviceList

!DEC$ ATTRIBUTES DEFAULT, STDCALL, DECORATE, ALIAS:'GetRawInputDeviceList' :: GetRawInputDeviceList

!DEC$ ATTRIBUTES REFERENCE :: pRawInputDeviceList
TYPE(RAWINPUTDEVICELIST), INTENT(OUT), DIMENSION(:):: pRawInputDeviceList
!DEC$ ATTRIBUTES REFERENCE :: puiNumDevices
INTEGER(PUINT), INTENT(INOUT):: puiNumDevices
!DEC$ ATTRIBUTES REFERENCE:: cbSize
INTEGER(UINT), INTENT(IN):: cbSize
END FUNCTION GetRawInputDeviceList
END INTERFACE

END MODULE RawInputFunctions

 

PROGRAM WindowsRawInput

USE USER32
USE KERNEL32
USE ifwinty
USE RawInputStructures
USE RawInputFunctions

IMPLICIT NONE

 

INTEGER(UINT):: ret

INTEGER(PUINT):: NumDevices
INTEGER(UINT):: cbSize
TYPE(RAWINPUTDEVICELIST), DIMENSION(1:4):: DeviceList


NumDevices = SIZE(DeviceList)
cbSize = SIZEOF(DeviceList)

ret = GetRawInputDeviceList(DeviceList, NumDevices, cbSize)
WRITE(*,*) 'GetRawInputDeviceList = ', ret

IF (ret .LT. 0) WRITE(*,*) 'GetLastError = ', GetLastError()
WRITE(*,*) 'NumDevices = ', NumDevices
READ(*,*)

STOP

END PROGRAM WindowsRawInput

 

Please advise what is wrong here.

Labels (1)
0 Kudos
1 Solution
jimdempseyatthecove
Honored Contributor III
793 Views

cbSize is the size of a RAWINPUTDEVICELIST, not the size of the array of RAWINPUTDEVICELISTs

Try

cbSize = SIZEOF(RAWINPUTDEVICELIST)

 

Also, cbSize is to be passed by value, not reference.

 

Hint, also, if you continue to have issues, write a C callable shell function (that works) and call that from Fortran.

You can look at the disassembly code to check the values of the arguments.

 

Jim Dempsey

 

View solution in original post

0 Kudos
3 Replies
jimdempseyatthecove
Honored Contributor III
794 Views

cbSize is the size of a RAWINPUTDEVICELIST, not the size of the array of RAWINPUTDEVICELISTs

Try

cbSize = SIZEOF(RAWINPUTDEVICELIST)

 

Also, cbSize is to be passed by value, not reference.

 

Hint, also, if you continue to have issues, write a C callable shell function (that works) and call that from Fortran.

You can look at the disassembly code to check the values of the arguments.

 

Jim Dempsey

 

0 Kudos
andrew_4619
Honored Contributor III
784 Views

This works, notice th

module RawInputStructures
    use ifwinty
    type, bind(c) :: rawinputdevicelist
        integer(handle):: hdevice
        integer(dword) :: dwtype
    end type rawinputdevicelist
    interface
        function GetRawInputDeviceList(pRawInputDeviceList, puiNumDevices, cbSize) BIND(C,NAME="GetRawInputDeviceList") 
            import
            !DIR$ ATTRIBUTES STDCALL :: GetRawInputDeviceList
            !GCC$ ATTRIBUTES STDCALL :: GetRawInputDeviceList
            INTEGER(UINT)          :: GetRawInputDeviceList
            integer(handle), value    :: pRawInputDeviceList
            INTEGER(handle), value :: puiNumDevices
            INTEGER(UINT), value   :: cbSize
        END FUNCTION GetRawInputDeviceList
    end interface
end module RawInputStructures
Program WindowsRawInput
    USE USER32
    USE KERNEL32, only: GetLastError
    USE ifwinty
    USE RawInputStructures, only: RAWINPUTDEVICELIST, GetRawInputDeviceList
    use, intrinsic :: iso_c_binding, only: c_loc
    IMPLICIT NONE
    INTEGER(UINT):: ret
    INTEGER(PUINT), target:: NumDevices
    INTEGER(UINT):: cbSize
    TYPE(RAWINPUTDEVICELIST), target:: DeviceList(50)
    NumDevices = 0
    cbSize     = SIZEOF(DeviceList(1))
    ret = GetRawInputDeviceList(  0_handle, transfer( c_loc(NumDevices), 0_handle), cbSize )
    write(*,*) 'GetRawInputDeviceList = ', ret
    if (ret .lt. 0) write(*,*) 'GetLastError = ', GetLastError()
    write(*,*) 'NumDevices = ', NumDevices
    ret = GetRawInputDeviceList( transfer( c_loc(DeviceList), 0_handle),&
                                 transfer( c_loc(NumDevices), 0_handle), cbSize )
    write(*,*) 'GetRawInputDeviceList = ', ret
    if (ret .lt. 0) write(*,*) 'GetLastError = ', GetLastError()
    write(*,*) 'NumDevices = ', NumDevices
    read(*,*)
    stop
end program Windowsrawinput

e first call to get the number of devices which on my system was 15!

 

R_K
Beginner
691 Views

Dear Andrew,

thank you for code. It is very instructive much more than solution of specific problem.

 

RK 

0 Kudos
Reply