- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
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
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
コピーされたリンク
4 返答(返信)
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
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.
EXPORT has to be implicit in declaration of a subprogram with C binding.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
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.
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.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
Quoting - nbunderson
!DEC$ ATTRIBUTES VALUE :: gobj,user_data
integer(KIND=int_ptr_kind()) :: user_data, gobj, col
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.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
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.
