This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
Re: Access to module variables from C without BIND(C) and C_LOC()?
- From: Tobias Burnus <burnus at net-b dot de>
- To: Mikhail Titov <mlt at gmx dot us>
- Cc: fortran at gcc dot gnu dot org
- Date: Tue, 06 Apr 2010 11:22:12 +0200
- Subject: Re: Access to module variables from C without BIND(C) and C_LOC()?
- References: <001101cad55f$f5b74ac0$e125e040$@us>
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