(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