Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

using window API CreateProcess inside g95 fortran code

Status
Not open for further replies.

khaddad

Technical User
Dec 22, 2010
3
CA
Greetings:

I have a batchfile that I would like to run (execute) from inside fortran code that am compiling using g95. I have found source code on the internet for this but it is specific to commercial compilers such as IVF. The code in this case would make use of modules specific to IVF. Are you aware of an implementation for CreateProcess in g95 code.

Thanks
Kimo.
 
Thanks.

I have actually implemented the "call system" command option. But in my case I am calling the external batch file in an iterative mode. So I have many calls placed to this batch file. I am considering the "createprcess" option because the batchfile will run in the background and without the dos command window popping up every time the call is made. Also the call system command slows down the program when called many times.

 
Well, try execute_command_line call with asynch process execution argument (if this Fortran 2008 feature is implemented in your compiler version).

Batch file is processed by cmd shell - the program which opens its own console window. I think you can't suppress this window creation by CreateProcess or any other start shell mechanism (may be I'm wrong;).
 
You need to do something like this
Code:
program launcher
   integer, parameter:: BOOL = 4, POINTER_LEN = 4, DWORD = 4, HANDLE = 4
   integer, parameter:: WORD = 4
   integer, parameter:: LPVOID = POINTER_LEN, LPSTR = POINTER_LEN
   integer, parameter:: LPBYTE = POINTER_LEN, LPCSTR = POINTER_LEN
   integer (LPCSTR), parameter:: NULL = 0 
   TYPE T_PROCESS_INFORMATION
   SEQUENCE
      integer(HANDLE) hProcess ! knowns  HANDLE 
      integer(HANDLE) hThread ! knowns  HANDLE 
      integer(DWORD) dwProcessId ! knowns  DWORD 
      integer(DWORD) dwThreadId ! knowns  DWORD 
   END TYPE
   TYPE T_STARTUPINFO
   SEQUENCE
      integer(DWORD) cb ! knowns  DWORD 
      integer(LPSTR) lpReserved ! knowns  LPSTR 
      integer(LPSTR) lpDesktop ! knowns  LPSTR 
      integer(LPSTR) lpTitle ! knowns  LPSTR 
      integer(DWORD) dwX ! knowns  DWORD 
      integer(DWORD) dwY ! knowns  DWORD 
      integer(DWORD) dwXSize ! knowns  DWORD 
      integer(DWORD) dwYSize ! knowns  DWORD 
      integer(DWORD) dwXCountChars ! knowns  DWORD 
      integer(DWORD) dwYCountChars ! knowns  DWORD 
      integer(DWORD) dwFillAttribute ! knowns  DWORD 
      integer(DWORD) dwFlags ! knowns  DWORD 
      integer(WORD) wShowWindow ! knowns  WORD 
      integer(WORD) cbReserved2 ! knowns  WORD 
      integer(LPBYTE) lpReserved2 ! knowns  LPBYTE 
      integer(HANDLE) hStdInput ! knowns  HANDLE 
      integer(HANDLE) hStdOutput ! knowns  HANDLE 
      integer(HANDLE) hStdError ! knowns  HANDLE 
   END TYPE
   interface
      function CreateProcess ( &
         lpApplicationName, &
         lpCommandLine, &
         lpProcessAttributes, &
         lpThreadAttributes, &
         bInheritHandles, &
         dwCreationFlags, &
         lpEnvironment, &
         lpCurrentDirectory, &
         lpStartupInfo, &
         lpProcessInformation) &
      bind(C,name='CreateProcessA@40')
      import
         integer:: CreateProcess
         integer (LPCSTR) lpApplicationName ! LPCSTR lpApplicationName
         character*(*) lpCommandLine ! LPSTR lpCommandLine
         integer (POINTER_LEN):: LP_PROCESS_ATTRIBUTES
         integer (POINTER_LEN):: LP_SECURITY_ATTRIBUTES
         integer(BOOL) bInheritHandles ! BOOL bInheritHandles
         integer(DWORD) dwCreationFlags ! DWORD dwCreationFlags
         integer(LPVOID) lpEnvironment ! LPVOID lpEnvironment
         integer(LPCSTR) lpCurrentDirectory ! LPCSTR lpCurrentDirectory
         TYPE (T_STARTUPINFO), pointer:: lpStartupInfo
         TYPE (T_PROCESS_INFORMATION):: lpProcessInformation
      end function

      function GetLastError () &
      bind (C, name='GetLastError@0')
      import
         integer (DWORD):: GetLastError
      end function
   end interface
   TYPE (T_STARTUPINFO):: si
   TYPE (T_PROCESS_INFORMATION):: pi
   integer zero(18)
   integer launched, err

   zero = 0
   si = transfer (zero, si)
   si%CB = 68 ! sizeof(si) returns 72 so you need to do some packing
   print *, 'Size of si ', si%CB

   pi = transfer (zero, pi)

   launched = CreateProcess ( &
      NULL, & ! app name
      'c:\\windows\\system32\\notepad.exe', & ! command line string
      0, &  ! process attr
      0, &  ! thread attr
      0, &  ! inherit handles
      0, &  ! creation flags
      0, &  ! environment
      NULL, & ! current directory
      si, & ! startup info
      pi)  ! process info
   print *, 'Result is ', launched

   err = GetLastError ()
   print *, 'Last error ', err
   print *, '87 means incorrect parameter'
   print *, 'Process Handle ', pi%hProcess
   print *, 'Process thread ', pi%hThread
   print *, 'Process id ', pi%dwProcessId
   print *, 'Thread id ', pi%dwThreadId
   stop
   end
If you get unresolved externals on CreateProcess_, copy libkernel32.a from lib to lib\gcc-lib\i686-pc-mingw32\4.1.2
 
You'll need to play around with the parameter types. If you're passing in NULL instead of the actual value, then it needs to be changed accordingly. I haven't figured out how to to get it to accept both yet. For some reason, I keep on getting error 87 so something is not quite right: possibly alignment.
 
Hi ArkM

You can supress the window creation by CreateProcess by putting the sixth argument (the creation flag) as CREATE_NO_WINDOW instead og 0. Here is a short piece from a program, that starts a process without a window and waits infinitety for it to end.

Code:
	str = 'djpeg32 -bmp -scale 2/8 -outfile XXX.bmp XXX.jpg' // char(0)

	call ZeroMemory(LOC(si),sizeof(si))
	si.cb = sizeof(si)
	call ZeroMemory(LOC(pi),sizeof(pi))

	dwCreate = CREATE_NO_WINDOW	! value = #08000000
	lret = CreateProcess(0,str,0,0,FALSE,dwCreate,0,0,LOC(si),LOC(pi))

	if(lret.ne.0) then
	   status = WaitForSingleObject(pi.hProcess,INFINITE)
	   status = CloseHandle(pi.hProcess)
	   status = CloseHandle(pi.hThread)
	else
	   status = MessageBox(hDlg,'Error'C,'DJPEG32'C,MB_OK)
	endif
 
Thanks gullipe, g95 produces an error:

"Unexpected array reference"

And it points to the code line:
function CreateProcess ( &

I did copy the libkernel32.a file to the location you indicated. It seems then that g95 still does not recognize the reference to the CreateProcess function?
 
You need the latest version of g95. Some of the earlier versions do not have bind(C,name) implemented.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top