- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have always been using this method to call functions in a dynamically loaded DLL: INTERFACE logical function Check_Security_DLL(itype) BIND(C, NAME="Check_Security_DLL") integer(4) :: itype [value] end function Check_Security_DLL END INTERFACE pointer (p_CheckSecurity, Check_Security_DLL) if(.not. LibLoaded) then dll_handle = LoadLibrary('Tec1.dll'//char(0)) if (dll_Handle /= 0) then i_CheckSecurity = GetProcAddress(dll_handle, "Check_Security_DLL"C) if (i_CheckSecurity /= 0) then p_CheckSecurity = i_CheckSecurity LibLoaded = .true. endif endif endif if (LibLoaded) then result = Check_Security_DLL(type) endif
However I get these warnings if I switch on F2008 checking:
D:\ToolsetIncs\Check_SecF.F90(23): warning #7028: Integer pointer non-standard
D:\ToolsetIncs\Check_SecF.F90(17): warning #7372: Procedures as pointees is not supported in Fortran 2008 standard. [CHECK_SECURITY_DLL]
So I guess there is a new method, however the Samples do not have an example for dynamically loading the DLL and how to call a function in the DLL.
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
Ah yes I was looking in MixedLanguage, not DLL. I see it now thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
sorry just a followup - is the "abstract" keyword required here? What if it is not specified?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If it isn't specified then the compiler thinks you're declaring an actual external procedure. You should use it here.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Now full f2003 compliance...
Can you remove the dependence on the interface specification for GetProcAddress by surrounding its invocation with TRANSFER? I generally write out the result variable as being of type C_PTR for gfortran; TRANSFER would mean that it would work either way.
Also that Arguments argument to FormatMessage: shouldn't it be typed as a pointer to an array of TYPE(T_VA_LIST) rather than a scalar? Or perhaps just TYPE(C_PTR) by value. In the former case, one could use C_F_POINTER to get a pointer to an array addressed from C_NULL_PTR; in the latter case just passing C_NULL_PTR directly would serve instead of the ifort NULL extension.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, one could just use the result of GetProcAddress in a TRANSFER directly, but I thought it was clearer this way, especially as one was testing it for NULL.
As for FormatMessage, Arguments is optional (_In_opt_ in MSDN), so passing a NULL is exactly what one would do to omit it in C. Here NULL is just the name of a constant from IFWINTY, not an extension.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
We are kind of on different wavelengths here, Steve. I was thinking in terms of
p_USERFUNC = TRANSFER(GetProcAddress (hModule=dll_handle, & lpProcName="USERFUNC"//C_NULL_CHAR),p_USERFUNC)
The point being that this syntax would work even given a 'rationalized' interface for GetProcAddress that defined the result as TYPE(C_PTR). The extensions used in kernel32.f90 are pre-f2003 and were necessitated by the lack of standardized methods for interfacing to C. In code that was intended to only be compiled by ifort the use of TRANSFER above looks nonsensical, but it would be more transportable.
As for FormatMessage::Arguments, MSDN says it's an array of values, but kernel32.f90 specifies it as
!DEC$ ATTRIBUTES REFERENCE, ALLOW_NULL :: Arguments TYPE(T_VA_LIST) Arguments ! va_list* Arguments
To be consistent with MSDN documentation, I think Arguments should be DIMENSION(*) rather than a scalar. I hadn't noticed that FormatMessage is expanded as a generic. In this style, NULL as actual argument is, as you say, not an extension. However, don't you need 4 generic flavors given that there are two possible independent interfaces for lpBuffer and Arguments? If lpBuffer and Arguments are both sent NULL, isn't the invocation ambiguous?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Point taken about GetProcAddress.
And yes, the interface for FormatMessage in KERNEL32 is questionable. We inherited this one from Microsoft and have refined hundreds of these over the years, but this one doesn't seem to have been looked at closely. I'll add it to my (very long) list of APIs to reconsider.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page