- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi there,
I am having an issue with FORTRAN/C interop using Intel FORTRAN that I'm hoping someone can help me with.
It is illustrated by the contrived example below:
library.f90:
module m implicit none abstract interface subroutine callback(data_ptr) bind (c) use iso_c_binding type(c_ptr), intent(in), value :: data_ptr end subroutine callback end interface end module subroutine library_fn(c_fn_ptr, data_ptr) bind(c) ! Is this still the recommended way to indicate the exported symbols even with FORTRAN 2003 support? !DEC$ ATTRIBUTES DLLEXPORT :: library_fn use iso_c_binding use m implicit none type(c_funptr), intent (in), value :: c_fn_ptr type(c_ptr), intent (in), value :: data_ptr integer(kind=C_INTPTR_T) :: address procedure(callback), pointer :: f_fn_ptr address = transfer(data_ptr, address) write(*,'("library::library_fn::address = ", "0x",Z12)') address call c_f_procpointer(c_fn_ptr, f_fn_ptr) call f_fn_ptr(data_ptr) end subroutine library_fn
main.cxx:
#include <iostream> using namespace std; // Implemented by FORTRAN dll extern "C" void library_fn(void (*fn_ptr)(void*), void* data_ptr); void callback(void* data_ptr) { cout << "main::callback::data_ptr = " << data_ptr << endl; int i = *static_cast<int*>(data_ptr); cout << "main::callback::i = " << i << endl; } int main() { int i = 792; cout << "main::main::i = " << i << endl; void* data_ptr = static_cast<void*>(&i); cout << "main::main::data_ptr = " << data_ptr << endl; library_fn(&callback, data_ptr); }
Building on Win64:
Intel(R) Visual Fortran Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 12.0.3.175 Build 20110309
ifort /c library.f90 lib /out:library.lib library.obj cl main.cxx library.lib
Building on Linux:
GNU Fortran (GCC) 4.9.2 20150212 (Red Hat 4.9.2-6)
gfortran -shared -fPIC library.f90 -o library.so g++ main.cxx library.so
Sample run on Win64:
[thwill@PSEUK1149(master)]$ ./main.exe main::main::i = 792 main::main::data_ptr = 00000000002CFE70 library::library_fn::address = 0x 2CFE70 main::callback::data_ptr = 00000000002CFE58 <---- INCORRECT! main::callback::i = 2948720
Sample run on 64-bit Linux:
[thwill@pseuk1149-centos7-vm(master)]$ ./a.out main::main::i = 792 main::main::data_ptr = 0x7ffc97963a54 library::library_fn::address = 0x7FFC97963A54 main::callback::data_ptr = 0x7ffc97963a54 <---- CORRECT! main::callback::i = 792
As you can see the data pointer has become "corrupted" on Win64 when it is passed back from the FORTRAN into the C.
FORTRAN is not something I use very often and until a fortnight ago I restricted myself to FORTRAN-77, so I may be making a stupid mistake, but given it works with gfortran perhaps not?
Any ideas?
Regards,
Tom Williams
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I do not see the error with the 15.0 and later compilers.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thomas W. wrote:
.. FORTRAN is not something I use very often and until a fortnight ago I restricted myself to FORTRAN-77, so I may be making a stupid mistake, but given it works with gfortran perhaps not?
Note it's "Fortran" now! https://en.wikipedia.org/wiki/Fortran
As mentioned by mecej4, more recent incarnations of the compiler including the current release, compiler 17 update 1, work as expected.
By the way, with respect to name-mangling that can take across the compilers and platforms with mixed language applications, you may want to look into the optional NAME= specifier with BIND(C attribute: https://software.intel.com/en-us/node/678426
[fortran]
subroutine library_fn(c_fn_ptr, data_ptr) bind(c) ! Is this still the recommended way to indicate the exported symbols even with FORTRAN 2003 support? !DEC$ ATTRIBUTES DLLEXPORT :: library_fn [/fortran]
Note this has mostly to do with OS, not the language and on Windows, you may want to keep the option of DEF files in mind: https://msdn.microsoft.com/en-us/library/28d6s79h.aspx
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi folks,
Thanks for the replies. I have tried out the latest Intel Fortran compiler and can confirm that it seems to fix the issue, so I guess this was a compiler bug?
Regards,
Tom
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Good to hear Tom. Yes, this is an apparent defect in the older 12.0 compiler fixed in a later release. Nothing in the example code shown can be attributed to the incorrect pointer value.
Many thanks to everyone who contributed here.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Just a final note that it actually works with Intel Fortran 12 update 9; the failing version was update 3.
Regards,
Tom
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page