- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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'.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page