无法从R控制台访问spatstat.geom导出的.C函数的技术咨询
CRAN上的R包spatstat.geom定义了一批.C函数,并通过NAMESPACE文件中的语句useDynLib(spatstat.geom, .registration=TRUE, .fixes="SG_")导出。但无法通过常规的.C语法在包外部访问这些函数:例如该包内的nncross.ppp()函数可调用.C(SG_knnXinterface, ..., PACKAGE = "spatstat.geom"),但外部调用时会报错:
Error in .C("SG_nnXinterface", PACKAGE = "spatstat.geom", 2) : "SG_nnXinterface" not available for .C() for package "spatstat.geom"
可复现示例
- 可正常找到函数:
.C("spline_value", PACKAGE = "cobs") - 无法找到函数:
.C("SG_nnXinterface", PACKAGE = "spatstat.geom")
提出的问题
- 如何从R控制台访问这些C函数?
- 该问题是否与spatstat.*系列包的嵌套结构有关?
附sessionInfo()信息
R version 4.3.2 (2023-10-31) Platform: x86_64-pc-linux-gnu (64-bit) Running under: Ubuntu 22.04.3 LTS Matrix products: default BLAS: /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.10.0 LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.10.0 locale: [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C LC_TIME=de_BE.UTF-8 [4] LC_COLLATE=en_US.UTF-8 LC_MONETARY=de_BE.UTF-8 LC_MESSAGES=en_US.UTF-8 [7] LC_PAPER=de_BE.UTF-8 LC_NAME=C LC_ADDRESS=C [10] LC_TELEPHONE=C LC_MEASUREMENT=de_BE.UTF-8 LC_IDENTIFICATION=C time zone: Europe/Amsterdam tzcode source: system (glibc) attached base packages: [1] stats graphics grDevices utils datasets methods base other attached packages: [1] spatstat.geom_3.2-7.007 spatstat.data_3.0-4 loaded via a namespace (and not attached): [1] compiler_4.3.2 deldir_2.0-2 Matrix_1.6-5 spatstat.utils_3.0-4 [5] tools_4.3.2 grid_4.3.2 polyclip_1.10-6 lattice_0.22-5
问题1:如何从R控制台访问这些C函数?
问题核心是useDynLib的.registration=TRUE参数——该参数会让R将这些C函数注册为仅包内部可见,不会暴露给外部调用。
有两种可行的解决方式:
- 修改包源码重新编译:
- 下载
spatstat.geom的源码,修改NAMESPACE文件,移除.registration=TRUE参数(默认值为FALSE)。 - 重新编译安装包后,即可通过
.C("SG_nnXinterface", PACKAGE = "spatstat.geom")正常调用。
- 下载
- 通过包内导出的R函数间接调用:
- 若不想修改源码,可利用包中已导出的R函数(如
nncross.ppp())作为入口,间接触发对应C函数的逻辑。但这种方式需要熟悉包的内部实现,且无法直接向C函数传递自定义参数。
- 若不想修改源码,可利用包中已导出的R函数(如
注意:直接调用包内部C函数属于非官方用法,后续包版本更新可能修改函数签名或实现,导致代码失效。
问题2:该问题是否与spatstat.*系列包的嵌套结构有关?
无关。问题的本质是useDynLib的.registration=TRUE参数设置,和spatstat系列包的嵌套依赖结构没有关系。
即使是单个独立包,只要设置了.registration=TRUE,其注册的C函数也会被限制为仅内部可见,外部无法直接调用。你测试的cobs包能正常调用,是因为它的NAMESPACE未设置.registration=TRUE,C函数是直接暴露的。
内容的提问来源于stack exchange,提问作者Knarpie

