我使用SWIG生成包装代码以从R语言中访问C代码。包装器代码使用R externalptr
类型来保存对C指针的引用。在某些情况下,这些指针在C端是NULL,在显示时在R中显示为nil值。在R方面,is.null()
上的is.na()
和externalptr
都会返回FALSE
。例如:
> val = librdf_query_results_get_binding_value(results, 2)
> val
An object of class "_p_librdf_node_s"
Slot "ref":
<pointer: (nil)>
> class(val@ref)
[1] "externalptr"
> is.null(val@ref)
[1] FALSE
> is.na(val@ref)
[1] FALSE
从上面的代码输出中可以看出,ref
广告位包含externalptr
,其为&#34; nil&#34;。如何从R中确定C中的这个指针是否为NULL?
如果你想在上下文中看到代码,它可以在GitHub中找到: https://github.com/ropensci/redland-bindings/blob/master/R/redland/inst/tests/test.redland_base.R#L40
答案 0 :(得分:3)
为了完整性,这是我使用的解决方案。根据@DirkEddelbuettel的建议,它需要C侧的功能和R侧的功能。 C函数是:
#include <Rinternals.h>
SEXP isnull(SEXP pointer) {
return ScalarLogical(!R_ExternalPtrAddr(pointer));
}
R中的包装函数是:
is.null.externalptr <- function(pointer) {
stopifnot(is(pointer, "externalptr"))
.Call("isnull", pointer)
}
有关在R中使用的示例:
> p <- new("externalptr")
> p
<pointer: (nil)>
> is.null.externalptr(p)
[1] TRUE
答案 1 :(得分:3)
上面的C
解决方案最优雅,但编译器可能并不总是可用。不需要编译代码的解决方案可能类似于:
identical(pointer, new("externalptr"))
但是,如果对象具有自定义属性,则无效。如果是这种情况,您可以这样做:
isnull <- function(pointer){
a <- attributes(pointer)
attributes(pointer) <- NULL
out <- identical(pointer, new("externalptr"))
attributes(pointer) <- a
return(out)
}
再次比C解决方案更复杂,但可以在任何平台上以简单的脚本工作。