From mtmorgan at fhcrc.org  Thu Jan 27 04:03:38 2011
From: mtmorgan at fhcrc.org (Martin Morgan)
Date: Wed, 26 Jan 2011 19:03:38 -0800
Subject: [Rd] Dealing with R list objects in C/C++
In-Reply-To: <A02FE3A5690A624994A6A0BC0DEEA920072898926A@NYKPCMMGMB05.INTRANET.BARCAPINT.COM>
References: <A02FE3A5690A624994A6A0BC0DEEA920072898926A@NYKPCMMGMB05.INTRANET.BARCAPINT.COM>
Message-ID: <4D40E08A.6070100@fhcrc.org>

On 01/26/2011 02:56 PM, Wayne.Zhang at barclayscapital.com wrote:
> Hi,
> 
> I'd like to construct an R list object in C++, fill it with relevant data, and pass it to an R function which will return a different list object back.  I have browsed through all the R manuals, and examples under tests/Embedding, but can't figure out the correct way.  Below is my code snippet:
> 
>     #include <Rinternals.h>
> // Rf_initEmbeddedR and other setups already performed
> 
>     SEXP arg, ret;
> 
>     // this actually creates a pairlist.  I can't find any API that creates a list
> PROTECT(arg = allocList(3));

Allocate a list of length 3 via SEXPTYPE VECSXP

      PROTECT(arg = allocVector(VECSXP, 3));

> 
> // I want the first element to be type integer, second double, and third a vector.
>     INTEGER(arg)[0]  = 1;            // <- runtime exception: "INTEGER() can only be applied to a 'integer', not a 'pairlist'

set the first element of the list to an integer vector of length 1, and
assign a value

      SET_VECTOR_ELT(arg, 0, allocVector(INTSXP, 1));
      INTEGER(VECTOR_ELT(arg, 0))[0] = 1

or more succinctly

      SET_VECTOR_ELT(arg, 0, ScalarInteger(1));

>     REAL(arg)[1] = 2.5;               // control never reached here

and the second element

      SET_VECTOR_ELT(arg, 1, ScalarReal(2.5));

>     VECTOR_PTR(arg)[2] = allocVector(REALSXP, 4);

and for the third allocate a REALSXP and then fill

      SET_VECTOR_ELT(arg, 2, allocVector(REALSXP, 4));

next lines should be ok as REAL(VECTOR_ELT(arg, 2))[0] = 10.0; or with
less typing as

      double *x = REAL(VECTOR_ETL(arg, 2));
      x[0] = 10.0; x[1] = 11.0; x[2] = 12.0; x[3] = 13.0;

>     REAL(VECTOR_PTR(arg)[2])[0] = 10.0;
>     REAL(VECTOR_PTR(arg)[2])[1] = 11.0;
>     REAL(VECTOR_PTR(arg)[2])[2] = 12.0;
>     REAL(VECTOR_PTR(arg)[2])[3] = 13.0;
> 
>     PROTECT(call = lang2(install(entryPoint.c_str()), arg));

not sure where entryPoint.c_str() is coming from, but

     PROTECT(call = lang2(install("fun"), arg));

with some debate about whether install("fun") should be PROTECT'ed.

> 
> ret = R_tryEval(call, R_GlobalEnv, &errorOccurred);

likely PROTECT(ret = ...) while checking errorOccurred, etc.

Hope that helps,

Martin

> 
> 
> I'll be grateful if you can point me to any online docs/samples.
> 
> Thanks in advance,
> Wayne
> 
> _______________________________________________
> 
> 
i!
>  ce at 1 Churchill Place, London, E14 5HP.  This email may relate to or be sent from other members of the Barclays Group.
> _______________________________________________
> 
> 	[[alternative HTML version deleted]]
> 
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel


-- 
Computational Biology
Fred Hutchinson Cancer Research Center
1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109

Location: M1-B861
Telephone: 206 667-2793



[Rd] Dealing with R list objects in C/C++
Martin Morgan