Я вызываю код C через .Call("foo", <args>)
, где foo вызывает другие функции C , вычисляет результат и возвращает его. Результатом является список длины 3, и я бы назвал этот список. С этой целью, Foo делает это:Как построить именованный список (SEXP) для возврата из функции C, вызванной с .Call()?
/* Construct result list from variables containing the results */
SEXP res = PROTECT(allocVector(VECSXP, 3)); /* list of length 3 */
SET_VECTOR_ELT(res, 0, ScalarReal(a)); /* numeric(1) */
SET_VECTOR_ELT(res, 1, somenumericvector); /* numeric(<some length>) */
SET_VECTOR_ELT(res, 2, ScalarInteger(i)); /* integer(1) */
/* Name components and return */
SEXP nms = PROTECT(allocVector(STRSXP, 3)); /* names as SEXP */
char *nms_ = CHAR(STRING_ELT(nms, 0)); /* pointer to names */
char *names[3] = {"result_numeric", "result_numeric_vector", "result_integer"};
for(i = 0; i < 3; i++) nms_[i] = names[i];
setAttrib(res, R_NamesSymbol, nms);
UNPROTECT(1);
return res;
Является ли это/правильный способ построения именованного списка длины 3?
Функция C действительно возвращается к R, но как только я назначаю вывод переменной в R, я сразу же получу ошибку сегментации. Что может быть неправильным? Я может поставить «отладочный на» (простой printf("...\n")
прямо перед выше «вернуть Рез,» и они выполняются в порядке Есть ли удобный способ для отладки кода C называется из R
FWIW это было бы намного проще с API-интерфейсом Rcpp. – nrussell
И это еще проще, если вы задали имена из R. – nicola
Я знаю, но меня интересует «простой» способ. –