(j3.2006) Should character strings be interoperable with char arrays?
Bill Long
longb
Tue Jul 24 12:36:10 EDT 2007
Aleksandar Donev wrote:
> Hello,
>
> This is a (random) rant about C Interop based on some codes I was writing
> today...just to illustrate the pains of C Interop for strings (which are not
> interoperable with char arrays unless LEN=1) and C_LOC.
>
In the example below, the problems have almost nothing to do with
character variables, but rather the pain of dealing with arrays of pointers.
> This is a procedure that writes several variables defined a mesh to a database
> file to be read by a visualization software. It takes an array of strings and
> an array of arrays (C pointers), one per variable:
>
> void write_point_mesh(const char *filename, int ub, int npts, float *pts,
> int nvars, int *vardim, const char * const *varnames,
> float **vars)
>
> Fortran interface:
>
> SUBROUTINE write_point_mesh(filename, ub, npts, pts, nvars, &
> vardim, varnames, vars) BIND(C)
> IMPORT
> CHARACTER(C_CHAR), DIMENSION(*), INTENT(IN) :: filename
> INTEGER(C_INT), VALUE :: ub, npts, nvars
> REAL(C_FLOAT), DIMENSION(3*npts) :: pts
> INTEGER(C_INT), DIMENSION(nvars) :: vardim
> TYPE(C_PTR), DIMENSION(nvars) :: varnames
> TYPE(C_PTR), DIMENSION(nvars) :: vars
> END SUBROUTINE
>
> Usage in an actual code requires using CHARACTER arrays instead of strings,
>
Not for the filename variable. You can supply a character variable with
length > 1 as the actual argument (typically
actual_file_name//C_NULL_CHAR).
> and adding TARGET to all the arrays:
>
Not for the cases of the pts and vardim arguments.
The only arguments that involve some form of contortions here are the
two that are effectively arrays of C pointers. The underlying type of
the arguments is not the issue.
You have created an array of type C pointer and assigned the
corresponding pointers to each of the elements. A C programmer would be
faced with basically the same actions. The bottom line is that this is
just a clumsy interface that you are stuck using.
Cheers,
Bill
> CHARACTER(KIND=C_CHAR), TARGET :: &
> v_string(2)=(/"v",C_NULL_CHAR/), &
> rho_string(4)=(/"r","h","o",C_NULL_CHAR/)
>
> CALL write_point_mesh(... varnames=(/C_LOC(v_string), C_LOC(rho_string)/), &
> vars=(/C_LOC(velocities), C_LOC(densities)/))
>
> The only way to use the hack we provided to allow strings to be passed as
> actuals corresponding to char arrays is to write wrappers.
>
> It should be easier than this!
> Best,
> Aleks
>
>
--
Bill Long longb at cray.com
Fortran Technical Support & voice: 651-605-9024
Bioinformatics Software Development fax: 651-605-9142
Cray Inc., 1340 Mendota Heights Rd., Mendota Heights, MN, 55120
More information about the J3
mailing list