作者Neisseria (Neisseria)
看板C_and_CPP
标题[问题] 动态函式库存在,程式却找不到
时间Mon Oct 24 19:01:04 2016
开发平台(Platform): (Ex: Win10, Linux, ...)
Debian GNU/Linux Jessie
编译器(Ex: GCC, clang, VC++...)+目标环境(跟开发平台不同的话需列出)
g++ 4.9.2
go 1.7.3
额外使用到的函数库(Library Used): (Ex: OpenGL, ...)
None
问题(Question):
我在练习将 Golang 转出的 shared library 和 C++ 程式结合
程式已经写好了,也转成 shared library (.so)
编译时也没跳错误讯息,编译指令如下:
$ g++ -o main main.cpp -L. -ldoubler
但是执行时,程式却说找不到 shared library,讯息如下:
libdoubler.so: cannot open shared object file: No such file or directory
蛮诡异的,那个 .so 档就在同一个资料夹中 Orz
我另外把这个程式包成 Ruby gem,给 Ruby 程式呼叫,可正确执行
我也在 Mac 上用同样的 main.cpp,也可正确执行
这个蛮难 google 的,因为会找到一大堆没装 xxx library 之类的讨论串 = =...
喂入的资料(Input):
None
预期的正确结果(Expected Output):
错误结果(Wrong Output):
./main: error while loading shared libraries:
libdoubler.so: cannot open shared object file: No such file or directory
程式码(Code):(请善用置底文网页, 记得排版)
# main.cpp
#include <iostream>
#include "libdoubler.h"
using std::cout;
using std::endl;
int main() {
cout << DoubleFloat(1.2) << endl;
}
补充说明(Supplement):
PTT 惠我良多
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 175.180.170.133
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1477306869.A.45D.html
1F:推 CoNsTaR: Linux 是不是要给相对/绝对路径,不像 Windows 只要在同 10/24 19:04
2F:→ CoNsTaR: 目录下就可以 10/24 19:04
3F:→ descent: export LD_LIBRARY_PATH=. 试试看 10/24 19:05
这招有效。不过可以简要说明一下原理吗?感恩
※ 编辑: Neisseria (175.180.170.133), 10/24/2016 19:08:40
4F:推 Bencrie: 另外你可以用 ldd 查连结的状况 10/24 20:05
5F:→ Bencrie: LD_PRELOAD 这个变数你也可以玩玩看 10/24 20:05
6F:→ uranusjr: 类 Unix 系统预设只会到特定的地方找动态资料库, 所以 10/24 20:19
7F:→ uranusjr: 如果你不把 .so (或其他副档名) 放在那些地方, 就必须用 10/24 20:19
8F:→ uranusjr: 环境变数来告诉作业系统额外的路径; . 代表「当前路径」 10/24 20:20
9F:→ uranusjr: LD_PRELOAD 则是用来告诉作业系统「不论如何, 在执行任 10/24 20:21
10F:→ uranusjr: 何程式前都载入此函式库」; 这很容易造成问题, 请避免 10/24 20:22
11F:→ uranusjr: LD_LIBRARY_PATH 比较好一些, 但还是应该尽可能避免 10/24 20:23
12F:推 LiloHuang: LD_PRELOAD 可以用来做 API hooking 还满值得玩玩看 10/24 21:45
13F:推 LPH66: 既然提了 LD_LIBRARY_PATH 那就顺便提 rpath 10/25 01:00
14F:→ LPH66: 在连结时加上 -rpath . 这个连结器参数就能让 loader 知道 10/25 01:00
15F:→ LPH66: so 档也要在工作目录下找; 不过由於这是连结器 ld 的参数 10/25 01:02
16F:→ LPH66: 所以如果是经由 gcc/g++ 呼叫的话要用 -Wl 引导 (小写L) 10/25 01:03
17F:→ LPH66: 要写成 -Wl,-rpath,. 或写成 -Wl,-rpath -Wl,. 10/25 01:03
18F:→ LPH66: -rpath 也能指定相对执行档的位置, 这时参数要使用 $ORIGIN 10/25 01:05
19F:→ LPH66: 这七个字表示执行档所在目录 10/25 01:05
20F:→ LPH66: 例如 -Wl,-rpath,'$ORIGIN/../lib' 10/25 01:06
21F:→ LPH66: (因为这里必须要用 $ 字本身而非变数, 所以要用引号括起来) 10/25 01:06
22F:推 lovejomi: export LD_LIBRARY_PATH= 请问一下这种方法一般程式user 10/25 15:23
23F:→ lovejomi: 怎麽可能会,换句话说他的用途感觉很狭隘不是? 10/25 15:23
24F:→ uranusjr: 所以才有套件管理员啊, 自动帮你把东西装到读得到的地方 10/25 15:41
25F:→ uranusjr: 像 PATH 环境变数的道理也是一样 10/25 15:41
26F:→ uranusjr: 设环境变数和 rpath 都是 programmer 才需要知道的东西 10/25 15:42
※ 编辑: Neisseria (112.104.128.230), 12/24/2018 06:37:13