- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm trying to use the FormatMessage function to obtain the error message when windows functions fail. The functions I'm particularly interested in are CopyFile and CreateProcess. The follow subroutine is my first attempt to get the error message but so far I've had no joy.
subroutine w32_CheckError
!**********************************************************
! Check for Windows W32 Error And Display Message
!**********************************************************
use dfwin, NULLPTR => NULL
use kernel32
implicit none
! Local Variables
character*255 :: string
integer :: nchar
nchar = FormatMessage(ior(FORMAT_MESSAGE_ALLOCATE_BUFFER,ior(FORMAT_MESSAGE_FROM_SYSTEM, &
FORMAT_MESSAGE_IGNORE_INSERTS)), &
NULL, &
GetLastError(), &
int(MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),DWORD), & ! Default language
! LANG_NEUTRAL, & ! Default language
string, &
255, &
NULL)
! Display the string.
if(nchar.gt.0) then
call grp_message('Windows Error: '//trim(string(1:nchar)))
endif
return
end subroutine
When I try this the contents of string is garbled. Has anyone successfully used this in a FORTRAN context that can tell me what I'm doing wrong.
Thanks in advance.
Steve
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
dannycat wrote:FORMAT_MESSAGE_ALLOCATE_BUFFER is the f90 way to do things with dynamic memory. It doesn't in itself cause a problem, but you have to do 3 things to implement the dynamic memory approach.I had FORMAT_MESSAGE_ALLOCATE_BUFFER in dwFlags which may be what caused a problem otherwise they are essentially the same.
- You have to allocate the memory and get its handle.
FORMAT_MESSAGE_ALLOCATE_BUFFER tells FormatMessage to allocate memory for the output string. To capture the handle, you want to change the way you invoke FormatMessage a little. First put
use ISO_C_BINDING
among your USE statements. Then declare
integer, parameter :: nbits = bit_size(0_HANDLE)/bit_size(0_byte)
this gives you the size of a pointer in bytes in case you want the same code to work in both 32- and 64-bit mode. Now you can declare
character(nbits,C_CHAR) capture
which gives you the right size of variable to capture the C_PTR that FormatMessage will return as the pointer to the error string in the memory it allocated for you. Now you can change the lpBuffer argument of FormatMessage from string to capture and the nsize argument to 1 because at minimum we need the space for the terminating ASCII NUL. - You need to convert the C_PTR that FormatMessage returned to something Fortran can digest. For this, we need to USE the module that has the conversion subroutine
use string_utils
and change the declaration of string to
character(:,C_CHAR), pointer :: string
Now we can carry out the conversion given the right kind of subroutine:
call CharStar2Deferred(transfer(capture,C_NULL_PTR),string)
string now has your error message and is already just the right length. - Since the dynamic memory wasn't allocated as a Fortran ALLOCABABLE, we are going to need to deallocate it somehow after use. At the end of the subroutine you need
nchar = LocalFree(transfer(capture,0_HANDLE))
to do this.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- I think the syntax with IANY([]) is easier to read than multiple IOR()s and I'm not the only one who thinks that.
- Why do you put keywords in comments rather than simply using keyword syntax which is at least as clear and combines compiler checking with your comments?
- I also think it's more natural from the Fortran programmers point of view to cast the message to a deferred-length scalar rather than an array of CHARACTER*1 elements. For example "Error while "//string//": "//message_buffer would be OK for the scalar but not the array.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
![](/skins/images/8B6E2C8F64F54CBD7F7262AA46F575DA/responsive_peak/images/icon_anonymous_message.png)
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page