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

Win32/x64 checking current executable??

DavidWhite
Valued Contributor II
746 Views

I have a test program that I use to test all of the calls in my DLL app.

Currently, this is a Win32 program calling a Win32 DLL - all good.

I now want to use the same code, built as x64 to test the x64 version of my DLL, and so I need the program to be able to detect whether it was built as Win32 or x64.  I have been using GetBinaryType from Kernel32 - this correctly detects whether a program (exe or DLL) is 32 or 64 bit, but only when called from a Win32 build.

How can I call GetBinaryType properly from an x64 build?

I'm using

USE KERNEL32

USE, intrinsic :: iso_c_binding

Integer(LPDWORD) :: BinaryType

ret=GetBinaryType(TRIM(exename)//ACHAR(0), LOC(BinaryType))

Thanks,

David

0 Kudos
1 Solution
JVanB
Valued Contributor II
746 Views

Well, it seems to me to be simpler to just inquire about the size of an intptr_t, but GetBinaryType seems to work, too:

program p
   use ISO_C_BINDING
   implicit none
   integer, parameter :: BOOL = C_INT, DWORD = C_LONG
   integer, parameter :: MAX_PATH = 260, HANDLE = C_INTPTR_T
   interface
      function GetModuleHandle(lpModuleName) bind(C,name='GetModuleHandleA')
         import
         implicit none
         !GCC$ ATTRIBUTES STDCALL :: GetModuleHandle
         !DEC$ ATTRIBUTES STDCALL :: GetModuleHandle
         integer(HANDLE) GetModuleHandle
         character(KIND=C_CHAR), intent(in) :: lpModuleName(*)
      end function GetModuleHandle
   end interface
   interface
      function GetModuleFileName(hModule,lpFileName,nSize) bind(C,name='GetModuleFileNameA')
         import
         implicit none
         !GCC$ ATTRIBUTES STDCALL :: GetModuleFileName
         !DEC$ ATTRIBUTES STDCALL :: GetModuleFileName
         integer(DWORD) GetModuleFileName
         integer(HANDLE), value :: hModule
         character(KIND=C_CHAR) :: lpFileName(*)
         integer(DWORD), value :: nSize
      end function GetModuleFileName
   end interface
   interface
      function GetBinaryType(lpApplicationName,lpBinaryType) bind(C,name='GetBinaryTypeA')
         import
         implicit none
         !GCC$ ATTRIBUTES STDCALL :: GetBinaryType
         !DEC$ ATTRIBUTES STDCALL :: GetBinaryType
         integer(BOOL) GetBinaryType
         character(KIND=C_CHAR), intent(in) :: lpApplicationName
         integer(DWORD) lpBinaryType
      end function GetBinaryType
   end interface
   character(KIND=C_CHAR), pointer :: lpModuleName(:)
   integer(HANDLE) ModuleHandle
   integer(DWORD) res1
   integer(BOOL) res2
   character(MAX_PATH+1,C_CHAR) path
   integer(DWORD) BinaryType

   write(*,'(a,i0,a)') 'This is a ',BIT_SIZE(0_C_INTPTR_T),'-bit build.'
   call C_F_POINTER(C_NULL_PTR,lpModuleName,[0])
   ModuleHandle = GetModuleHandle(lpModuleName)
   res1 = GetModuleFileName(ModuleHandle,path,len(path))
   res2 = GetBinaryType(path,BinaryType)
   write(*,'(a,i0)') 'Binary Type = ',BinaryType
end program p

 

View solution in original post

0 Kudos
2 Replies
JVanB
Valued Contributor II
747 Views

Well, it seems to me to be simpler to just inquire about the size of an intptr_t, but GetBinaryType seems to work, too:

program p
   use ISO_C_BINDING
   implicit none
   integer, parameter :: BOOL = C_INT, DWORD = C_LONG
   integer, parameter :: MAX_PATH = 260, HANDLE = C_INTPTR_T
   interface
      function GetModuleHandle(lpModuleName) bind(C,name='GetModuleHandleA')
         import
         implicit none
         !GCC$ ATTRIBUTES STDCALL :: GetModuleHandle
         !DEC$ ATTRIBUTES STDCALL :: GetModuleHandle
         integer(HANDLE) GetModuleHandle
         character(KIND=C_CHAR), intent(in) :: lpModuleName(*)
      end function GetModuleHandle
   end interface
   interface
      function GetModuleFileName(hModule,lpFileName,nSize) bind(C,name='GetModuleFileNameA')
         import
         implicit none
         !GCC$ ATTRIBUTES STDCALL :: GetModuleFileName
         !DEC$ ATTRIBUTES STDCALL :: GetModuleFileName
         integer(DWORD) GetModuleFileName
         integer(HANDLE), value :: hModule
         character(KIND=C_CHAR) :: lpFileName(*)
         integer(DWORD), value :: nSize
      end function GetModuleFileName
   end interface
   interface
      function GetBinaryType(lpApplicationName,lpBinaryType) bind(C,name='GetBinaryTypeA')
         import
         implicit none
         !GCC$ ATTRIBUTES STDCALL :: GetBinaryType
         !DEC$ ATTRIBUTES STDCALL :: GetBinaryType
         integer(BOOL) GetBinaryType
         character(KIND=C_CHAR), intent(in) :: lpApplicationName
         integer(DWORD) lpBinaryType
      end function GetBinaryType
   end interface
   character(KIND=C_CHAR), pointer :: lpModuleName(:)
   integer(HANDLE) ModuleHandle
   integer(DWORD) res1
   integer(BOOL) res2
   character(MAX_PATH+1,C_CHAR) path
   integer(DWORD) BinaryType

   write(*,'(a,i0,a)') 'This is a ',BIT_SIZE(0_C_INTPTR_T),'-bit build.'
   call C_F_POINTER(C_NULL_PTR,lpModuleName,[0])
   ModuleHandle = GetModuleHandle(lpModuleName)
   res1 = GetModuleFileName(ModuleHandle,path,len(path))
   res2 = GetBinaryType(path,BinaryType)
   write(*,'(a,i0)') 'Binary Type = ',BinaryType
end program p

 

0 Kudos
DavidWhite
Valued Contributor II
746 Views

Thanks, that is certainly a neater way of doing it.

I was trying to adapt the code I wrote to detect 64-bit Excel, which I can do from the Win32 version without any problems.

Thanks,

David

0 Kudos
Reply