- 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