This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Access to module variables from C without BIND(C) and C_LOC()?


Hello,

On 04/06/2010 10:05 AM, Mikhail Titov wrote:
> I have a mixed language program (fortran and C). I compile it using gcc 4.4.0 under mingw. I would like to use allocatable arrays instead of fixed ones. Currently fixed arrays are defined within named COMMON blocks. Allocatable arrays cannot be defined in common blocks. Furthermore `bind(C)` and `allocatable` attributes cannot be used together.
>
> I define such array variable `arr` in a module let's say `wrap_me`. I noticed that I can directly access my array from C code using `__wrap_me_MOD_arr` name besides standard(?) way of using `type(C_PTR)` pointer with `bind(C)` attribute and C_LOC() with `arr` that has `target` attribute as well. Though `direct` access uses clutter name, it is somewhat shorter to define within fortran code and therefore more convenient to use.
>
> However I can't find any note whether accessing module variable using `__modulename_MOD_variablename` is portable and safe to use.
>   

Well, using __modulename_MOD_variablename is highly unportable: The name
mangling is compiler dependent. Thus, the program will only work with
gfortran. Additionally, an allocatable array has a structure (cf. a
derived TYPE in Fortran or "struct" in C) and is thus called array
descriptor or dope vector, which contains in addition to the data also
the arrays bounds and some more (compiler-dependent) information. Using
__modulename_MOD_variablename only works if the first element is the
pointer to the array and the rest of the information comes only later.
(This is seemingly the case at the moment.)

One portable way is to pass the array as argument, cf.

use iso_c_binding
implicit none

interface
  subroutine func(x,n) bind(C)
    import
    integer(c_int) :: x(*), n
  end subroutine
end interface

integer(c_int), allocatable :: a(:)
allocate(a(100))
call func(a, size(a))
end

which is portable. Note, however, that the compiler might do a copy
in/copy out for the function call and thus the address of the array
passed to "func" might be not valid after the call. (For gfortran, no
copy in/out should happen if you pass the whole array.)

If your array needs to be remotely accessible (global/extern variable)
and allocatable, there is currently no standard conform way to do so.

Note 1: There will be a technical report (TR 29113) on further
interoperability with C, but before November it won't be stable and thus
it won't be implemented in gfortran until then; cf.
ftp://ftp.nag.co.uk/sc22wg5/N1801-N1850/N1812.txt and
ftp://ftp.nag.co.uk/sc22wg5/N1751-N1800/N1761.txt

Note 2: For array descriptor interoperability, see also
http://chasm-interop.sourceforge.net/

Tobias


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]