Às 02:25 de 14/03/2026, Therneau, Terry M., Ph.D. via R-help escreveu:
I've often used the following paradym in C code to define a list object 
returned to R

      static const char *outnames[]= {"dvec", "A", "Ainv",  "P", ""};
      SEXP rval, stemp;
      double *dvec, *A, *Ainv;
      int *P;


      PROTECT(rval = mkNamed(VECSXP, outnames));
      stemp=  SET_VECTOR_ELT(rval, 0, allocVector(REALSXP, nc));
      dvec= REAL(stemp);
      stemp = SET_VECTOR_ELT(rval, 1, allocMatrix(REALSXP, nc, nc));
      A = REAL(stemp);

Then the code puts values into dvec[i] and etc. and finally returns rval.

I'm missing how to do this when returning a complex value.   I've looked 
through the
"Writing R extension" manual and have come up dry.  What am I missing?

Terry T.


Hello,

Use CPLXSXP, COMPLEX and Rcomplex.
There are also Rf_asComplex, Rf_isComplex and Rf_ScalarComplex.
See section 5.2 [1] for a description of R type Rcomplex.

Maybe this example can help.



//---
// file: test_complex.c
#include <R.h>
#include <Rinternals.h>

SEXP complex1(const SEXP size) {
    SEXP cval;
    Rcomplex *cvec;
    const R_xlen_t n = Rf_asInteger(size);

    PROTECT(cval = allocVector(CPLXSXP, n));
    cvec = COMPLEX(cval);
    for(R_xlen_t i = 0; i < n; i++) {
        cvec[i].r = i + 1.0;
        cvec[i].i = 2.0 * (i + 1);
    }
    UNPROTECT(1);
    return cval;
}

SEXP complex2(void) {
    static const char *outnames[]= {"dvec", "complex", ""};
    SEXP rval, stemp;
    double *dvec;
    Rcomplex *cvec;

    const R_xlen_t nc = 2;

    PROTECT(rval = mkNamed(VECSXP, outnames));
    // reals
    stemp = SET_VECTOR_ELT(rval, 0, allocVector(REALSXP, nc));
    dvec= REAL(stemp);
    for(R_xlen_t i = 0; i < nc; i++)
        dvec[i] = 0.5 * (i + 1);
    // complex
    stemp = SET_VECTOR_ELT(rval, 1, allocVector(CPLXSXP, nc));
    cvec = COMPLEX(stemp);
    for(R_xlen_t i = 0; i < nc; i++) {
        cvec[i].r = i + 1.0;
        cvec[i].i = 2.0 * (i + 1);
    }
    // done
    UNPROTECT(1);
    return rval;
}

Now the R source to test the above

#---
# file: test_complex.R
dynLoad <- function(dynlib) {
  dynlib <- paste0(dynlib, .Platform$dynlib.ext)
  dyn.load(dynlib)
}
dynUnload <- function(dynlib) {
  dynlib <- paste0(dynlib, .Platform$dynlib.ext)
  dyn.unload(dynlib)
}

args <- c("CMD", "SHLIB", "test_complex.c")
system2("R", args = args)

dynLoad("test_complex")

complex1 <- function(size) .Call("complex1", as.integer(size))
complex2 <- function() .Call("complex2")

complex1(10L)
#> [1] 1+ 2i 2+ 4i 3+ 6i 4+ 8i 5+10i 6+12i 7+14i 8+16i 9+18i 10+20i
complex2()
#> $dvec
#> [1] 0.5 1.0
#>
#> $complex
#> [1] 1+2i 2+4i

dynUnload("test_complex")




[1] https://cran.r-project.org/doc/manuals/r-release/R-exts.html#Interface-functions-_002eC-and-_002eFortran

Hope this helps,

Rui Barradas

______________________________________________
[email protected] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide https://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.

Reply via email to