À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.