Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29234 ディスカッション

Access Violations, mixed languages, dll exporting

nbunderson
ビギナー
501件の閲覧回数
Hi, I'm trying to write a simple wrapper/binding for gtk+. And I've run across a problem that's new to me: This is where I am

I compile a C library "FGTK" that has a function:

GtkWidget* fgtk_glade(int argc, char *argv[], gchar *fname, gchar *widgname)

In addition to argc and argv it takes the name of an xml file that has all the information gtk needs for building a gui and the name of the top "widget". This xml file also contains the names of functions to be used as signal handlers. I would like for these functions to be written in fortran:

subroutine fgtk_get_color_callback(gobj, user_data) BIND(C,name='fgtk_get_color_callback')
!DEC$ ATTRIBUTES DLLEXPORT :: fgtk_get_color_callback


In order to get the C library to recognize my fgtk_get_color_callback subroutine (so it can connect the signals with the widget) i have to give it the DLLEXPORT attribute.

This works fine, the library will build the widget and my signal subroutine is called appropriately from the widget (or it appears to be).

The problem comes when I try to make another function call inside fgtk_get_color_callback, here's the whole module:

module gtk
...

INTERFACE
FUNCTION fgtk_glade(argv, argc, fname, widgname) bind(C,name='fgtk_glade')
!DEC$ ATTRIBUTES VALUE :: argv
USE gtk_constants
CHARACTER(len=*,kind=gchar),INTENT(in) :: fname, widgname, argc
integer(GINT) :: argv
integer(KIND=int_ptr_kind()) :: fgtk_glade
ENDFUNCTION
END INTERFACE

INTERFACE
FUNCTION fgtk_get_color(gobj) bind(C,name='fgtk_get_color')
!DEC$ ATTRIBUTES VALUE :: gobj
integer(KIND=int_ptr_kind()) :: gobj, fgtk_get_color
ENDFUNCTION
END INTERFACE

CONTAINS
! CALLBACKS *****************************************************************
subroutine fgtk_get_color_callback(gobj, user_data) BIND(C,name='fgtk_get_color_callback')
!DEC$ ATTRIBUTES DLLEXPORT :: fgtk_get_color_callback
!DEC$ ATTRIBUTES VALUE :: gobj,user_data
implicit none
integer(KIND=int_ptr_kind()) :: user_data, gobj, col
col = fgtk_get_color(gobj)
endsubroutine
...

endmodule gtk




I think the access violation is coming from my:
...
col = fgtk_get_color(gobj)
...
within

fgtk_get_color_callback

It may be that the binding's aren't correct but I think the problem is that I'm dllexporting a function symbol and then trying to do something fancy inside that. I haven't been able to find any help on this, and I'm afraid I really don't know how to debug run-time problems. I would greatly appreciate any help.


UPDATE:

I guess the problem is before the

col = fgtk_get_color(gobj)

call. I can replace that function call with a call to goo:

subroutine goo(gobj)
implicit none
integer(KIND=int_ptr_kind()) :: user_data, gobj, col
write(*,*)gobj
endsubroutine

And I get an access violation if I try to replace
write(*,*)gobj
with the uninitialized data objects:
write(*,*)user_data
or
write(*,*)col


endsubroutine

0 件の賞賛
4 返答(返信)
TimP
名誉コントリビューター III
501件の閲覧回数
I assume you have USE iso_c_binding; wouldn't the compiler give a fatal error without it? I doubt that you can mix iso_c_bnding and legacy ATTRIBUTE successfully this way; maybe the compiler ought to tell you that. So, if you required the value attribute in the declaration of those variables, the compiler may not have carried out your intent.
EXPORT has to be implicit in declaration of a subprogram with C binding.
Steven_L_Intel1
従業員
501件の閲覧回数
This code does not need a USE of ISO_C_BINDING. I've mentioned before that BIND(C) and ISO_C_BINDING are two independent pieces of the F2003 C interoperability features.

I don't spot anything obviously wrong here - it's ok to use DLLEXPORT/IMPORT with BIND(C). You can't use STDCALL with BIND(C) (just saying.)

You say you "think" the access violation is coming from the call. You should be able to tell this easily by looking at the traceback. If I were debugging it, I'd step through the disassembly of the call and see what was the exact instruction complaining. It could be that the gtk routine is trying to dereference gobj and getting it wrong because it is not passed properly. Dunno about that. But you would be better off to know exactly where the error occurred rather than guessing.
Jugoslav_Dujic
高評価コントリビューター II
501件の閲覧回数
Quoting - nbunderson
!DEC$ ATTRIBUTES VALUE :: gobj,user_data
integer(KIND=int_ptr_kind()) :: user_data, gobj, col


A style issue -- although it is not related with your access violation: if you're using standard C interoperability features, better use them all the way down than to mix them with old Visual Fortran extensions. The above lines should read:

use ISO_C_BINDINGS
type(C_PTR), value:: user_data, gobj
type(C_PTR):: col

I also don't see anything obvious in the code, but debugging it should be relatively easy -- start the program with F5 from the IDE, and when it stops the access violation, open the "Call Stack" window and examine the values of variables in the argument-lists.


nbunderson
ビギナー
501件の閲覧回数
Thank you Tim, Steve, and Jugoslav. The problem was actually in one of the C routines, which is why I couldn't get at it with the fortran debugger, however, depending on how I called that routine it was giving the access violation at very strange places which made it very difficult to track down. In the C routine I wrote I was attempting to use a variable that had not been set. It doesn't help that I'm learning C (and how to use all the debug tools in IVF) as I go here. Thanks again for all your help.
返信