golang os.Setenv 在 cgo C.dlopen 中不起作用?
golang os.Setenv does not work in cgo C.dlopen?
出于某种原因,我无法将 $LD_LIBRARY_PATH 设置为全局环境。我尝试使用 os.Setenv.
在 golang 代码中设置它
os.Setenv("LD_LIBRARY_PATH", my_library_paths)
lib := C.dlopen(C.CString(libpath), C.RTLD_LAZY)
我用另一个C++函数得到$LD_LIBRARY_PATH
,它显示正确。
但是 lib returns '' 和 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找不到依赖库。
我不知道 why.Hope 有人可以帮忙 me.Thanks!
您似乎正试图在同一进程中从 调用 os.Setenv("LD_LIBRARY_PATH", ...)
然后 C.dlopen()
。
来自手册页 dlopen(3):
Otherwise, the dynamic linker searches for the object as follows
...
If, at the time that the program was started, the environment variable LD_LIBRARY_PATH was defined to contain a colon-separated list of directories, then these are searched.
关键字是,程序启动时。我们可以在 glibc source elf/dl-load.c 中的 dlopen
的实现中看到它查看一个全局变量 __rtld_env_path_list.dirs
,该变量在搜索要加载的库时已经设置;它不查看$LD_LIBRARY_PATH
的当前值。
如果您想使用 LD_LIBRARY_PATH
在 C.dlopen
中查找内容,那么您需要在进程开始之前设置它(通过 运行 例如 LD_LIBRARY_PATH=/my/path go run my-app.go
).
正如 KJ Tsanaktsidis 正确回答的那样,LD_LIBRARY_PATH
在进程启动后没有任何效果;您必须在 开始该过程之前 设置它。
一种常用的技术是检查 LD_LIBRARY_PATH
的当前值,如果不合您的喜好,将其设置为新值 和 重新 exec
过程。
就是说,不清楚您为什么 想要 首先设置 LD_LIBRARY_PATH
。如果您使用绝对路径调用 dlopen
,dlopen
将愉快地打开一个不在 LD_LIBRARY_PATH
上的库。也就是说,而不是这样做:
os.Setenv("LD_LIBRARY_PATH", my_library_paths)
lib := C.dlopen(C.CString(libpath), C.RTLD_LAZY)
这样做:
lib := C.dlopen(C.CString(absolute_path_to_library), C.RTLD_LAZY)
出于某种原因,我无法将 $LD_LIBRARY_PATH 设置为全局环境。我尝试使用 os.Setenv.
在 golang 代码中设置它os.Setenv("LD_LIBRARY_PATH", my_library_paths)
lib := C.dlopen(C.CString(libpath), C.RTLD_LAZY)
我用另一个C++函数得到$LD_LIBRARY_PATH
,它显示正确。
但是 lib returns '
>> %!(EXTRA string=libhasp_linux_x86_64_demo.so: cannot open shared object file: No such file or directory)
表示$LD_LIBRARY_PATH在dlopen中不工作,cgo找不到依赖库。
我不知道 why.Hope 有人可以帮忙 me.Thanks!
您似乎正试图在同一进程中从 调用 os.Setenv("LD_LIBRARY_PATH", ...)
然后 C.dlopen()
。
来自手册页 dlopen(3):
Otherwise, the dynamic linker searches for the object as follows
...
If, at the time that the program was started, the environment variable LD_LIBRARY_PATH was defined to contain a colon-separated list of directories, then these are searched.
关键字是,程序启动时。我们可以在 glibc source elf/dl-load.c 中的 dlopen
的实现中看到它查看一个全局变量 __rtld_env_path_list.dirs
,该变量在搜索要加载的库时已经设置;它不查看$LD_LIBRARY_PATH
的当前值。
如果您想使用 LD_LIBRARY_PATH
在 C.dlopen
中查找内容,那么您需要在进程开始之前设置它(通过 运行 例如 LD_LIBRARY_PATH=/my/path go run my-app.go
).
正如 KJ Tsanaktsidis 正确回答的那样,LD_LIBRARY_PATH
在进程启动后没有任何效果;您必须在 开始该过程之前 设置它。
一种常用的技术是检查 LD_LIBRARY_PATH
的当前值,如果不合您的喜好,将其设置为新值 和 重新 exec
过程。
就是说,不清楚您为什么 想要 首先设置 LD_LIBRARY_PATH
。如果您使用绝对路径调用 dlopen
,dlopen
将愉快地打开一个不在 LD_LIBRARY_PATH
上的库。也就是说,而不是这样做:
os.Setenv("LD_LIBRARY_PATH", my_library_paths)
lib := C.dlopen(C.CString(libpath), C.RTLD_LAZY)
这样做:
lib := C.dlopen(C.CString(absolute_path_to_library), C.RTLD_LAZY)