我已经构建了一个用于与 R 中的 HDFql 交互的包。它依赖于 HDFql 2.1.0 提供的 R 包装器和 DLL/SO。这些包使用 DLL 在 Windows 中完美运行,但由于某种原因,HDFql 库 SO 无法在 Linux 环境中加载。我在Travis和本地 Docker Linux/R 容器上都试过这个。
函数中包含的相关代码hql_load()如下。假设 HDFql 被解压到当前目录“/hdfql-2.1.0”的一个文件夹中,这意味着
dllpath = c("/hdfql-2.1.0/lib/libHDFql.so", "/hdfql-2.1.0/wrapper/R/libHDFqlR.so")
我使用检查这些路径是否存在normalizePath(dllpath, mustWork = TRUE),并检查对象是否成功加载并出现在getLoadedDlls().
# ... starting at line 153 of connect.r ... #
wrapper.file = tempfile(fileext = ".r")
wrapper.lines = readLines(wrapperpath)
writeLines(wrapper.lines[-grep("dyn\\.load", wrapper.lines)],
wrapper.file)
# load DLLs
for (dll in dllpath) {
dyn.load(dll, local = FALSE, now = TRUE)
if (!dll %in% sapply(getLoadedDLLs(), function(x) normalizePath(x[["path"]], mustWork = FALSE))) {
stop("Error loading HDFql shared library object ", dll)
}
}
# load wrapper
wrapper = new.env(parent = .BaseNamespaceEnv)
tryCatch(
sys.source(wrapper.file, envir = wrapper, toplevel.env = packageName()),
error = function(e) {
stop("Failed to execute HDFql R wrapper.\n Additional Information:\n",
e)
}
)
assign("wrapper", wrapper, envir = hql)
invisible(NULL)
}
错误发生在对sys.sourceHDFql 提供的包装文件中的代码进行评估的调用中,特别是在初始化调用中。包装内容如下;请注意,在我上面的函数中,我dyn.load在评估它之前从包装器中删除了调用(预先加载了库)。
hdfql_operating_system = Sys.info()["sysname"]
if (hdfql_operating_system == "Windows")
{
dyn.load("HDFqlR.dll")
hdfql_shared_library <- "HDFqlR"
} else if (hdfql_operating_system == "Linux")
{
dyn.load("libHDFqlR.so")
hdfql_shared_library <- "libHDFqlR"
} else # macOS
{
dyn.load("libHDFqlR.dylib")
hdfql_shared_library <- "libHDFqlR.dylib"
}
rm(hdfql_operating_system)
#===========================================================
# INITIALIZE HDFQL R WRAPPER SHARED LIBRARY
#===========================================================
hdfql_initialize_status = .Call("_hdfql_initialize", PACKAGE = hdfql_shared_library)
错误:无法执行 HDFql R 包装器。
附加信息:
eval 中的错误(解析(wrapper.file),envir = wrapper):找不到/加载 HDFql 共享库“libHDFql.so”!
我已经对此进行了数周的故障排除,但进展甚微。谁能告诉我为什么库在 Linux 系统中没有正确加载?