- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have a function in a C++ program that calls a function in a Fortran DLL, passing a callback function to receive feedback from the Fortran DLL.
However, I have a problem linking the Fortran function into my C++ program, where it is declared as:
extern "C" { bool IMPORT FortranSetCounter(bool callback(int*)); }
In my Fortran DLL the function looks like this:
logical(c_bool) function FortranSetCounter(func) bind(c, name="FortranSetCounter") result(success)
!DEC$ ATTRIBUTES DLLEXPORT :: FortranSetCounter
implicit none
logical(c_bool) func
integer number
external func
number = 3
success = func(number)
end function
When I compile this code with Intel Fortran 19.1.3, I get to errors:
error #8809: An OPTIONAL or EXTERNAL dummy argument to a BIND(C) procedure is not interoperable
error #8812: This procedure dummy argument to the BIND(C) procedure is not interoperable. [FUNC]
If I remove "bind(c, name="FortranSetCounter")" from my function declaration, then the C++ program cannot link, since it cannot find the symbol _FortranSetCounter in the LIB file.
What am I doing wrong? And what can I do to overcome the problem.
Thanks inadvance for any help you can give me.
Andrew Bond
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here's a suggested rewrite:
logical(c_bool) function FortranSetCounter(func) bind(c, name="FortranSetCounter") result(success)
use, intrinsic :: iso_c_binding
!DEC$ ATTRIBUTES DLLEXPORT :: FortranSetCounter
implicit none
interface
function func (arg) bind(C)
import
logical(c_bool) :: func
integer(c_int), intent(in) :: arg
end function func
end interface
integer(c_int) :: number
number = 3
success = func(number)
end
I'll note that as of Fortran 2018 (supported in the 2021 compiler), interoperable procedures may have OPTIONAL arguments. The error message if you use EXTERNAL still mentions OPTIONAL, though, even if F18 standards checking is requested. I will report this to Intel.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What you're doing wrong is having the "func" argument declared EXTERNAL. An interoperable procedure requires that all its dummy arguments be interoperable, and simply declaring the function EXTERNAL doesn't do that.
What you need to do instead is replace "external func" with an interface block that declares func with bind(C), and declares its return and dummy arguments with interoperable types.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here's a suggested rewrite:
logical(c_bool) function FortranSetCounter(func) bind(c, name="FortranSetCounter") result(success)
use, intrinsic :: iso_c_binding
!DEC$ ATTRIBUTES DLLEXPORT :: FortranSetCounter
implicit none
interface
function func (arg) bind(C)
import
logical(c_bool) :: func
integer(c_int), intent(in) :: arg
end function func
end interface
integer(c_int) :: number
number = 3
success = func(number)
end
I'll note that as of Fortran 2018 (supported in the 2021 compiler), interoperable procedures may have OPTIONAL arguments. The error message if you use EXTERNAL still mentions OPTIONAL, though, even if F18 standards checking is requested. I will report this to Intel.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve
Thank you for your prompt and very comprehensive answer - that has worked perfectly.
My initial attempt was based on an old paper that I found on the web ... obviously not quite right in terms of the syntax needed nowadays.
Again many thanks
Andrew
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
One more thing. Since you're using logical(c_bool), be sure to compile with the /standard-semantics option (in Visual Studio, Fortran > Language > Enable Fortran 20xx semantics > Yes - the "xx" may be 03, 08 or 18 depending on your compiler version.) Otherwise, the Intel Fortran interpretation of true/false will differ from C's.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve
Another helpful tip, thanks.
I have been overcoming that issue by calls to a conversion function, c_to_f_bool(c_flag) result(f_flag), that I found on the web - quite possibly in one of your previous posts?
A compiler setting is much more elegant going forwards (since 95% of my work is in C++, with one only Fortran library). It is very difficult to switch from C++ to Fortran in quick succession - I've lost count of the number of times I forget to 'Call' subroutines in Fortran!
I found the option "Enable F2003 semantics", which I have set yo Yes. But I'm baffled that the dialog box does not say "Enable F2018 semantics" since I am running Intel Visual Fortran Compiler 19.1.3.311 [IA-32]. Am I missing some other setting?
Note that this Fortran library started off in Compaq Visual Fortran, so some settings may be 'old'.
Andrew
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The property was described as 2003 semantics until the oneAPI (2021) version.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the explanation. And for your help overall.
Andrew

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