Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28386 Discussions

Problem passing pointer from C to Intel FORTRAN and back to C

Thomas_W_
Beginner
393 Views

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

0 Kudos
5 Replies
mecej4
Honored Contributor III
393 Views

I do not see the error with the 15.0 and later compilers.

0 Kudos
FortranFan
Honored Contributor II
393 Views

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

0 Kudos
Thomas_W_
Beginner
393 Views

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

0 Kudos
Kevin_D_Intel
Employee
393 Views

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.

0 Kudos
Thomas_W_
Beginner
393 Views

Just a final note that it actually works with Intel Fortran 12 update 9; the failing version was update 3.

Regards,

Tom

0 Kudos
Reply