【问题标题】:Error: function is not available for .Call() for package X错误:函数不适用于包 X 的 .Call()
【发布时间】:2019-09-27 10:35:30
【问题描述】:

我刚刚开始尝试 Rcpp 包,所以请耐心等待。

我阅读了 Rcpp 小插图,并尝试了 Rcpp 文档中的一些给定示例。现在,我想我应该从包装 GLFW 库中的一些函数开始,这是一个用 C 编写的库。

所以我想我会从函数glfwInit 开始。我在一个名为 pixel 的包中编写了这个简单的 cpp 源文件,以将其包装在名称 glfw_init 下:

#include <Rcpp.h>
#include <GLFW/glfw3.h>
using namespace Rcpp;


//' @export
// [[Rcpp::export]]
int glfw_init() {

  return(glfwInit());
}

我在 RStudio 中工作,使用通常的冲洗和重复循环生成文档和构建包(我使用的是 roxygen2)。

函数导出到 R 和用户空间,所以如果我在 R 控制台中输入 glfw_init,我会得到:

function() {
    .Call('_pixel_glfw_init', PACKAGE = 'pixel')
}
<bytecode: 0x5558ece6f398>
<environment: namespace:pixel>

但是如果我尝试使用glfw_init() 运行它并得到错误:

Error in .Call("_pixel_glfw_init", PACKAGE = "pixel") : 
  "_pixel_glfw_init" not available for .Call() for package "pixel"

我觉得我遗漏了一些小的设置细节以使其正常工作...感谢任何帮助!

P.S.:根据 Konrad 的评论,我在这里发布了我在 RStudio 的构建窗格中获得的输出:

==> Rcpp::compileAttributes()

* Updated R/RcppExports.R

==> R CMD INSTALL --no-multiarch --with-keep.source pixel

g++ -std=gnu++11 -I"/usr/include/R/" -DNDEBUG  -I"/home/rmagno/R/x86_64-pc-linux-gnu-library/3.6/Rcpp/include" -D_FORTIFY_SOURCE=2  -fpic  -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong -fno-plt  -c glfw.cpp -o glfw.o
* installing to library ‘/home/rmagno/R/x86_64-pc-linux-gnu-library/3.6’
* installing *source* package ‘pixel’ ...
** using staged installation
** libs
g++ -std=gnu++11 -shared -L/usr/lib64/R/lib -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -o pixel.so RcppExports.o glfw.o -L/usr/lib64/R/lib -lR
installing to /home/rmagno/R/x86_64-pc-linux-gnu-library/3.6/00LOCK-pixel/00new/pixel/libs
** R
** byte-compile and prepare package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded from temporary location
** checking absolute paths in shared objects and dynamic libraries
** testing if installed package can be loaded from final location
** testing if installed package keeps a record of temporary installation path
* DONE (pixel)

P.S.2:这是我的命名空间:

# Generated by roxygen2: do not edit by hand

export(coords_rectangle)
export(coords_rectangular_lattice)
export(coords_segment)
export(coords_square)
export(display_matrix_int)
export(glfw_init)
export(lgl_matrix_to_coords_grid_segment)
export(lgl_matrix_to_coords_segment)
export(palette_for_quads)

P.S.3:新建文件R/pixel.R后:

#' @useDynLib pixel, .registration = TRUE
#' @importFrom Rcpp sourceCpp
NULL

当我尝试生成文档时出现此错误:

==> Rcpp::compileAttributes()

* Updated R/RcppExports.R

==> devtools::document(roclets = c('rd', 'collate', 'namespace'))

Updating pixel documentation
Loading pixel
Error in dyn.load(dllfile) : 
  unable to load shared object '/home/rmagno/sci/code/R/pkg/pixel/src/pixel.so':
  /home/rmagno/sci/code/R/pkg/pixel/src/pixel.so: undefined symbol: glfwInit
Calls: suppressPackageStartupMessages ... <Anonymous> -> load_dll -> library.dynam2 -> dyn.load
Execution halted

Exited with status 1.

【问题讨论】:

  • 您是否确保您的 Rcpp 代码已实际编译?从上面看,这并不明显:生成了 R 端的胶水代码,但这与 C++ 库的编译没有直接关系。
  • 您的NAMESPACE 文件是否包含所需的importFrom(Rcpp,evalCpp)useDynLib(pixel, .registration = TRUE)
  • @RalfStubner:不!确实没有。我应该手动执行吗?或者我如何告诉 roxygen2 从现在开始动态地执行它?
  • 使用 roxygen2 在将, .registration = TRUE 添加到@useDynLib pixel 后,您可以关注r-pkgs.org/src.html#cpp
  • @KonradRudolph 请参阅Rcpp-package 小插图中的“2.8 NAMESPACE”部分。

标签: r rcpp


【解决方案1】:

新错误表明您没有将 C++ 代码链接到 GLFW 库。您需要提供将库添加到PKG_LIBSsrc/Makevars 文件。请参阅编写 R 扩展手册中的 Using Makevars

【讨论】:

  • 还有很多来自 Rcpp 的关于如何与外部库链接的文档。我认为我们通常以 RcppGSL 为例,但还有很多其他的。
  • 谢谢@konrad-rudolph 和@dirk-eddelbuettel!我必须“清理并重建”才能使其正常工作,但现在可以了。
  • 对于其他阅读本文的人来说,这里是我发现有用的参考:Hadley's R packages | Section 13.4 MakefilesDirk's Rcpp Package vignette | Section 2.7
猜你喜欢
  • 1970-01-01
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-20
  • 2021-03-21
  • 2014-08-28
  • 1970-01-01
相关资源
最近更新 更多