Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs have moved to the Altera Community. Existing Intel Community members can sign in with their current credentials.
29322 Discussions

Further problem with using 'interface' for accessing C from Fortran

andy_in_oxford
New Contributor I
1,688 Views

 

I have a further problem with accessing C from Fortran. This follows on from my early problem that was solved. The program compiles but crashes on running. I am building and running the following in Windows using the Intel Fortran compiler. My program compiles eccodes.f90 and grib_f90.f90 correctly and grib_copy_msg.f90 compiles correctly. But when I try to run it an error is thrown:

 

I have the following: 

 

In the top part of the program grib_copy_msg.f90 I have:

 

program copy

 

  use eccodes

  implicit none

  integer  :: infile, igrib_in, status

 

  print *,'I am here 1'

  call codes_grib_new_from_file(infile, igrib_in, status)

  print *,'I am here 2'

 

.....

 

 

In eccodes.f90 there is:

 

 

subroutine codes_grib_new_from_file ( ifile, gribid , status)

    integer(kind=kindOfInt),intent(in)              :: ifile

    integer(kind=kindOfInt),intent(out)             :: gribid

    integer(kind=kindOfInt),optional,intent(out)    :: status

    !DIR$ ATTRIBUTES DLLEXPORT :: codes_grib_new_from_file

    print *,'I am here 1.1'

    call grib_new_from_file ( ifile, gribid , status)

end subroutine codes_grib_new_from_file 

 

 

codes_grib_new_from_file  is in a file called grib_f90.f90: 

 

 

 

  subroutine grib_new_from_file ( ifile, gribid , status)

      integer(kind=kindOfInt),intent(in)              :: ifile

      integer(kind=kindOfInt),intent(out)             :: gribid

      integer(kind=kindOfInt),optional,intent(out)    :: status

      integer(kind=kindOfInt)                         :: iret

 

      interface

        integer(c_int) function grib_f_new_from_file(ifile,&

                       gribid) bind(C, name="grib_f_new_from_file_")

          use iso_c_binding, only: c_int

          integer(c_int), intent(in) :: ifile

          integer(c_int), intent(out) :: gribid

        end function grib_f_new_from_file

      end interface

 

      print *,'I am here 1.2'

      iret=grib_f_new_from_file( ifile, gribid )

      print *,'I am here 1.3'

 

      if (present(status)) then

         status = iret

      else

         call grib_check(iret,'grib_new_from_file','')

      endif

  end subroutine grib_new_from_file

 

 

grib_f_new_from_file is in a C file called grib_fortran.c:

 

int grib_f_new_from_file_(int* fid, int* gid){

    int err = 0;

    FILE* f = get_file(*fid);

 

    grib_handle *h = NULL;

 

    if(f){

        h = grib_handle_new_from_file(0,f,&err);

        if(h){

            push_handle(h,gid);

            return GRIB_SUCCESS;

        } else {

            *gid=-1;

            return GRIB_END_OF_FILE;

        }

    }

 

    *gid=-1;

    return GRIB_INVALID_FILE;

}

int grib_f_new_from_file__(int* fid, int* gid){

    return grib_f_new_from_file_( fid, gid);

}

int grib_f_new_from_file(int* fid, int* gid){

    return grib_f_new_from_file_( fid, gid);

}

 

When I try to run it, I get the output:

 

I am here 1

I am here 1.1

I am here 1.2

 

The program then crashes.

 

What mistake have I made with the interface?  I read that I don't need to add an interface in if I use capitals for  GRIB_F_NEW_FROM_FILE, could someone provide an example in this context please?

0 Kudos
1 Solution
andy_in_oxford
New Contributor I
1,582 Views

Thank you Arjen and Jim for your replies on this topic. I have solved this now. 

The problem actually was that I hadn't set an environmental variable, the ECCODES_DEFINITION_PATH variable.

View solution in original post

0 Kudos
4 Replies
jimdempseyatthecove
Honored Contributor III
1,653 Views

Experiment by commenting out push_handle in your .c function and see if you make it to 'I am here 2'

If you do, then the problem is within push_handle.

--------------

Also, while your file has type .c, is it compiled as C or as C++?  If as C++ then attribute the function with extern "C"

IOW (if C++) while the entry point name can be resolved in C++ using C naming convention (compiler option), the calling API might not be resolved without the appropriate measures taken.

Jim Dempsey

0 Kudos
andy_in_oxford
New Contributor I
1,641 Views

Thanks Jim. I have tried running it with push_handle commented out and it still doesn't reach 'I am here 2'.

It is compiled as 'C'.

0 Kudos
Arjen_Markus
Honored Contributor II
1,632 Views

Just a few thoughts:

  • Has the argument ifile been given a value?
  • Can you add print statements to the C code to see where in the C function things go poof?
0 Kudos
andy_in_oxford
New Contributor I
1,583 Views

Thank you Arjen and Jim for your replies on this topic. I have solved this now. 

The problem actually was that I hadn't set an environmental variable, the ECCODES_DEFINITION_PATH variable.

0 Kudos
Reply