[Rd] best methods for strings and structures?

Jeff D. Hamann jeff.hamann at forestinformatics.com
Wed Mar 17 00:58:09 MET 2004

I'm trying to generate an R interface for a library that's commonly used and
I'm currently writing wrapper functions for file i/o and return an object
(list?) that contains the elements of the C structure. For example, reading
a file that contains:

    char            coeffs_filename[256];
    char            species_filename[256];
    unsigned long   use_random_error;
    unsigned long   random_seed;
    unsigned long   endemic_mortality;
    unsigned long   sdi_mortality;
    unsigned long   file_in_format;
    unsigned long   file_out_format;
    double          fixed_plot_radius;
    double          min_prism_dbh;
    double          baf;
    unsigned long   max_sample_size;
    unsigned long   use_precip_in_hg;

with an internal function and I'm building the return object using the
following code:

   PROTECT( ret_val = allocVector( VECSXP, 13 ) );
   SET_STRING_ELT( ret_val, 0, mkChar( cfg_rec.coeffs_filename) );
   SET_STRING_ELT( ret_val, 1, mkChar( cfg_rec.species_filename) );
   SET_VECTOR_ELT( ret_val, 2, ScalarInteger( cfg_rec.use_random_error ) );
   SET_VECTOR_ELT( ret_val, 3, ScalarInteger( cfg_rec.random_seed ) );
   SET_VECTOR_ELT( ret_val, 4, ScalarInteger( cfg_rec.endemic_mortality ) );
   SET_VECTOR_ELT( ret_val, 5, ScalarInteger( cfg_rec.sdi_mortality ) );
   SET_VECTOR_ELT( ret_val, 6, ScalarInteger( cfg_rec.file_in_format ) );
   SET_VECTOR_ELT( ret_val, 7, ScalarInteger( cfg_rec.file_out_format ) );
   SET_VECTOR_ELT( ret_val, 8, ScalarReal( cfg_rec.fixed_plot_radius ) );
   SET_VECTOR_ELT( ret_val, 9, ScalarReal( cfg_rec.min_prism_dbh ) );
   SET_VECTOR_ELT( ret_val, 10, ScalarReal( cfg_rec.baf ) );
   SET_VECTOR_ELT( ret_val, 11, ScalarInteger( cfg_rec.max_sample_size ) );
   SET_VECTOR_ELT( ret_val, 12, ScalarInteger( cfg_rec.use_precip_in_hg ) );

The resulting list contains :

> cfg
<CHARSXP: "coeffs.txt">
<CHARSXP: "species.txt">
[1] 1
[1] 109
[1] 1
[1] 1
[1] 4
[1] 4
[1] 11.77522
[1] 5.6
[1] 20
[1] 600
[1] 600

which seems to be acceptable, except for the two string at the beginning of
the list. I'm not sure the best method to return string in the return vector
and would like some advice on the best method to perform these operations.
My other question is this: Should I be using the insert() to assign these
values as attributes, like

   setAttrib( ret_val, install("use_random_error"), ScalarInteger(
cfg_rec.use_random_error ) );

since I'll be using these objects to pass back and forth from R to the model
library and using R as the simulation language in which I'll have to obtain
the values and build the resulting structures.


Jeff D. Hamann
Forest Informatics, Inc.
PO Box 1421
Corvallis, Oregon USA 97339-1421
jeff.hamann at forestinformatics.com

More information about the R-devel mailing list