Prev: unformatted files (again)
Next: Darvon online no prescription. Darvon online prescriptions with no membership. no prescription Darvon fedex delivery
From: Richard Maine on 6 Aug 2010 20:23 steve <kargls(a)comcast.net> wrote: > That does not answer my question. AFAIU, the > routine cannot be USEd in any other fortran > procedure. False. This sounds like a fairly basic misunderstanding of bind(c). Bind(c) does not mean that something cannot be invoked from Fortran. It just means that the invocation method is compatible with C. There are actually 2 completely different ways that a bind(c) module procedure can be invoked from Fortran code. The first way is via C interop. A bind(c) procedure is compatible with invocation via C. We know how to invoke C compatible procedures. Put the two together, and viola. This is independent of whether the procedure is in a module or not. It is a little wordy in this case because of the way that the type info_t is defined within the function. (I wouldn't do it that way, but it is allowed). That means I end up having to repeat the darned thing 3 times: 1) within the function itself, 2) within the interface body that is needed where we invoke the function, and 3 within the scope where we invoke the function because we'll need it to declare the actual argument. Wordy, but valid. The following wordy code works fine in g95 and prints 0 as expected. I have not touched a character of the original module. MODULE liter_cb_mod USE ISO_C_BINDING CONTAINS FUNCTION liter_cb(link_info) bind(C) USE ISO_C_BINDING IMPLICIT NONE INTEGER(c_int) liter_cb TYPE, bind(C) :: info_t INTEGER(c_int) :: type END TYPE info_t TYPE(info_t) :: link_info liter_cb = 0 END FUNCTION liter_cb END MODULE liter_cb_mod PROGRAM main USE ISO_C_BINDING interface FUNCTION liter_cb(link_info) bind(C) USE ISO_C_BINDING IMPLICIT NONE INTEGER(c_int) liter_cb TYPE, bind(C) :: info_t INTEGER(c_int) :: type END TYPE info_t TYPE(info_t) :: link_info END FUNCTION liter_cb end interface TYPE, bind(C) :: info_t INTEGER(c_int) :: type END TYPE info_t type(info_t) :: link_info write (*,*) liter_cb(link_info) END PROGRAM main Nag has a problem, but I'll cover that below. The second way to invoke a bind(c) procedure defined in a module is to USE the module. The rules for USE do not have any exceptions for bind(c) procedures. That means they are supposed to work. Yes, that means that, among other things, USEing the module has to pass along the information that the procedure in question is a bind(c) ones. But then USEing a module is supposed to simillarly pass along darn near everything. The following much shorter main program uses this method. I elided the module here because it is also unchanged from the original and one copy per post seemed enough PROGRAM main use liter_cb_mod TYPE, bind(C) :: info_t INTEGER(c_int) :: type END TYPE info_t type(info_t) :: link_info write (*,*) liter_cb(link_info) END PROGRAM main This also works fine and gives the expected result with g95. Again, Nag fails on it. The problem with the Nag compiler here isn't directly related to invoking a bind(c) module procedure. It has more to do with the bind(c) type used for the argument. In the version with the USE statement, Nag (v 5.2 on my Mac) gives me the message Incorrect data type INFO_T (expected INFO_T) for argument LINK_INFO (no. 1) of LITER_CB The message about finding INFO_T when it expected INFO_T looks confusing on the surface, but I think I can interpret it, realizing that there are 2 separate declarations of types named INFO_T. I'm thinking that someone at Nag forgot that bind(c) acts like sequence in that you can have 2 separate declarations that count as the same type. I'll throw in yet another lament that J3 failed to understand my suggestion that bind(c) types be referred to as a special sort (I carefully avoid saying type, kind, class or a bunch of other words that are basically synonymous in English, but have special meaning in Fortran) ot sequence type. They really do act like sequence. Pretty much everywhere the standard previously said "sequence", it had to be modified to say "sequence or bind(c)". There were several errors made in missing some such places in drafts of f2003. If we had just said that bind(c) was a sort of sequence, the errors would not have happened. Looks like compilers might be prone to exactly the same error. Think I'll submit a bug report on this one to Nag (after checking to make sure I have the most current patch release installed; I haven't checked that yet). Anyway, if I move the derived type definition out to module scope, where I would normally put it if I were writing the code, then the whole thing becomes MODULE liter_cb_mod USE ISO_C_BINDING TYPE, bind(C) :: info_t INTEGER(c_int) :: type END TYPE info_t CONTAINS FUNCTION liter_cb(link_info) bind(C) USE ISO_C_BINDING IMPLICIT NONE INTEGER(c_int) liter_cb TYPE(info_t) :: link_info liter_cb = 0 END FUNCTION liter_cb END MODULE liter_cb_mod PROGRAM main use liter_cb_mod type(info_t) :: link_info write (*,*) liter_cb(link_info) END PROGRAM main which works fine with both Nag and g95 on this machine. -- Richard Maine | Good judgment comes from experience; email: last name at domain . net | experience comes from bad judgment. domain: summertriangle | -- Mark Twain
From: dpb on 6 Aug 2010 21:36 Richard Maine wrote: .... > There are actually 2 completely different ways that a bind(c) module > procedure can be invoked from Fortran code. > > The first way is via C interop. A bind(c) procedure is compatible with > invocation via C. We know how to invoke C compatible procedures. Put the > two together, and viola. ... we have string music in an alto range. :) <Yeah, I know, groan, but I simply couldn't help it, Richard! :) > --
From: Richard Maine on 6 Aug 2010 22:02 dpb <none(a)non.net> wrote: > Richard Maine wrote: > ... > > > There are actually 2 completely different ways that a bind(c) module > > procedure can be invoked from Fortran code. > > > > The first way is via C interop. A bind(c) procedure is compatible with > > invocation via C. We know how to invoke C compatible procedures. Put the > > two together, and viola. ... we have string music in an alto range. :) > > <Yeah, I know, groan, but I simply couldn't help it, Richard! :) > Voila! :-) -- Richard Maine | Good judgment comes from experience; email: last name at domain . net | experience comes from bad judgment. domain: summertriangle | -- Mark Twain
From: glen herrmannsfeldt on 6 Aug 2010 23:59 Richard Maine <nospam(a)see.signature> wrote: (snip) > There are actually 2 completely different ways that a bind(c) module > procedure can be invoked from Fortran code. I presume that is in addition to calling a C function that calls the bind(c) module procedure from a passed c_funloc() pointer. -- glen
From: Richard Maine on 7 Aug 2010 00:32
glen herrmannsfeldt <gah(a)ugcs.caltech.edu> wrote: > Richard Maine <nospam(a)see.signature> wrote: > (snip) > > > There are actually 2 completely different ways that a bind(c) module > > procedure can be invoked from Fortran code. > > I presume that is in addition to calling a C function that > calls the bind(c) module procedure from a passed c_funloc() > pointer. Well yes, that's a third. I suppose I could have overlooked others as well. -- Richard Maine | Good judgment comes from experience; email: last name at domain . net | experience comes from bad judgment. domain: summertriangle | -- Mark Twain |