首页 > 解决方案 > golang os.Setenv 在 cgo C.dlopen 中不起作用?

问题描述

出于某种原因,我无法将 $LD_LIBRARY_PATH 设置为全局环境。我尝试在 golang 代码中使用 os.Setenv 进行设置。

os.Setenv("LD_LIBRARY_PATH", my_library_paths)

lib := C.dlopen(C.CString(libpath), C.RTLD_LAZY)

我使用另一个 C++ 函数来获取$LD_LIBRARY_PATH,它正确显示。但是 lib 返回 '<nil>',并且 C.dlerror() 显示

>> %!(EXTRA string=libhasp_linux_x86_64_demo.so: cannot open shared object file: No such file or directory)

表示 $LD_LIBRARY_PATH 在 dlopen 中不起作用,cgo 找不到依赖库。

我不知道为什么。希望有人能帮助我。谢谢!

标签: c++linuxgocgodlopen

解决方案


看起来您正在尝试调用os.Setenv("LD_LIBRARY_PATH", ...),然后C.dlopen()同一进程中调用。

从手册页dlopen(3)

否则,动态链接器按如下方式搜索对象

...

如果在程序启动时,环境变量 LD_LIBRARY_PATH 被定义为包含以冒号分隔的目录列表,则搜索这些目录。

关键短语是,在程序启动时。我们可以在 glibc 源代码 elf/dl-load.c 的实现中看到dlopen查看的是__rtld_env_path_list.dirs在搜索要加载的库时已经设置的全局变量;它不查看的当前值$LD_LIBRARY_PATH

如果你想用来LD_LIBRARY_PATH在 中查找东西C.dlopen,那么你需要在你的进程开始之前设置它(通过运行 eg LD_LIBRARY_PATH=/my/path go run my-app.go)。


推荐阅读