使用R Linux上的Dyn.load的问题加载共享库,但是等效的Windows构建效果很好



我已经构建了一个软件包,用于与R的HDFQL进行交互。它依赖于HDFQL 2.1.0提供的R包装器和DLL/SOS。这些软件包使用DLL在Windows中完美工作,但是由于某种原因,HDFQL库SOS无法在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.source呼叫中,以评估HDFQL提供的包装文件中的代码,而>在初始化调用中均具有。包装器内容在下面;请注意,在上面的功能中,我在对包装器进行评估之前删除了包装器的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中的错误(parse(wrapper.file(,envir = wrapper(:找不到/加载hdfql共享库'libhdfql.o'!

我已经对数周进行故障排除,几乎没有进展。谁能告诉我为什么库在Linux系统中未正确加载?

@ralfstubner的建议是正确的:问题是在Linux计算机上设置LD_LIBRARY_PATH,以包括HDFQL库。有趣的是,我仍然必须为dyn.load调用中的DLL提供完整的合格路径名称,并且无法使用Sys.setenvDLLpath参数到dyn.load来临时修改LD_LIBRARY_PATH ----相反,我已经在travis.yaml/Dockerfile上添加了一条线更新LD_LIBRARY_PATH

export LD_LIBRARY_PATH=${HDFQL_DIR}/lib:${HDFQL_DIR}/wrapper/R:$LD_LIBRARY_PATH

我仍然不明白为什么我无法使用例如。

解决问题
Sys.setenv(LD_LIBRARY_PATH = paste(dirname(dll), Sys.getenv("LD_LIBRARY_PATH"), sep = ":")

dyn.load(basename(dll), DLLpath = dirname(dll))

由于这两个命令(理论上(应该修改搜索路径以包括HDFQL目录。我很感谢可以解释这一点的任何答案。

我也很惊讶地发现,一旦我更新了LD_LIBRARY_PATH,我就被Windows Build在Windows Build上从未出现的环境绑定和名称空间问题击中 - 但这是一个单独的问题。

相关内容

最新更新