Очень распространенный вопрос о StackOverflow в отношении интеграции пакетов C ++ / R или C / R связан с ошибкой в dyn.load()
например,
> ## within R
> Error in .Call("function_c") : C symbol name "function_c" not in load table
согласно которому function_c
какая-то функция в C, как
SEXP function_c() {
Rprintf("Hello World!\n"); // manually changed
return(R_NilValue);
}
Эта ошибка возникает из-за многих типов ошибок, например, неправильное компиляция, неправильно названные функции, пользователь не использовал extern "C"
для кода Cpp и т. д.
Вопрос: есть ли способ просмотреть все «доступные» объекты, через которые пользователь мог бы загрузить dyn.load()
после компиляции?
Как насчет следующего? Я не уверен, что это покрывает все, но это должно быть близко:
# manipulate search() to get all loaded packages
loadedPkgs = grep('^package:', search(), value = TRUE)
loadedPkgs = gsub('package:', '', loadedPkgs, fixed = TRUE)
# add names here to make the results of lapply pretty
names(loadedPkgs) = loadedPkgs
allCRoutines = lapply(loadedPkgs, function(pkg) {
# see: https://stackoverflow.com/questions/8696158/
pkg_env = asNamespace(pkg)
# this works at a glance
check_CRoutine = function(vname) {
'CallRoutine' %in% attr(get(vname, envir = pkg_env), 'class')
}
names(which(sapply(ls(envir = pkg_env, all = TRUE), check_CRoutine)))
})
Объект немного длинный, поэтому я покажу только один пакет:
allCRoutines[['utils']]
# $utils
# [1] "C_crc64" "C_flushconsole" "C_menu" "C_nsl" "C_objectSize" "C_octsize" "C_processevents"# [8] "C_sockclose" "C_sockconnect" "C_socklisten" "C_sockopen" "C_sockread" "C_sockwrite"
В чем я не уверен, так это в том, что check_CRoutine
ловит все, что мы считаем актуальным для вашего вопроса. Я также не уверен, что это отвечает вашим основным интересам (могут ли эти объекты быть успешно переданы dyn.load
); возможно, возвращенные здесь процедуры могут быть переданы dyn.load
с try
обертка?
Других решений пока нет …