我知道我创造了赏金,但我不耐烦了,决定进行调查,现在我有一些对我有用的东西。我有一个与你的非常相似的 python 示例,除了尝试使用 Tkinter 显示在命令行上传递的图像外,它几乎没有任何作用,如下所示:
calebhattingh $ python imageview.py a.jpg
objc[84696]: Class TKApplication is implemented in both /Users/calebhattingh/anaconda/envs/py35/lib/libtk8.5.dylib and /System/Library/Frameworks/Tk.framework/Versions/8.5/Tk. One of the two will be used. Which one is undefined.
objc[84696]: Class TKMenu is implemented in both /Users/calebhattingh/anaconda/envs/py35/lib/libtk8.5.dylib and /System/Library/Frameworks/Tk.framework/Versions/8.5/Tk. One of the two will be used. Which one is undefined.
objc[84696]: Class TKContentView is implemented in both /Users/calebhattingh/anaconda/envs/py35/lib/libtk8.5.dylib and /System/Library/Frameworks/Tk.framework/Versions/8.5/Tk. One of the two will be used. Which one is undefined.
objc[84696]: Class TKWindow is implemented in both /Users/calebhattingh/anaconda/envs/py35/lib/libtk8.5.dylib and /System/Library/Frameworks/Tk.framework/Versions/8.5/Tk. One of the two will be used. Which one is undefined.
Segmentation fault: 11
发生的情况是 binary 文件 ~/anaconda/envs/py35/lib/python3.5/site-packages/PIL/_imagingtk.so 已链接到框架,而不是 env 中的 Tcl/Tk 库。您可以使用otool 查看链接设置:
(py35)? ~/anaconda/envs/py35/lib/python3.5/site-packages/PIL
calebhattingh $ otool -L _imagingtk.so
_imagingtk.so:
/System/Library/Frameworks/Tcl.framework/Versions/8.5/Tcl (compatibility version 8.5.0, current version 8.5.9)
/System/Library/Frameworks/Tk.framework/Versions/8.5/Tk (compatibility version 8.5.0, current version 8.5.9)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
看到那两个“框架”行了吗?对于 anaconda,我们不希望这样。我们想使用环境中的库。所以让我们改变它们吧!
首先备份你的二进制文件(以防你想恢复):
$ cp _imagingtk.so _imagingtk.so.bak
现在在命令行上运行它(假设您与envname/lib 在同一个文件夹中):
$ install_name_tool -change "/System/Library/Frameworks/Tk.framework/Versions/8.5/Tk" "@rpath/libtk8.5.dylib" _imagingtk.so
$ install_name_tool -change "/System/Library/Frameworks/Tcl.framework/Versions/8.5/Tcl" "@rpath/libtcl8.5.dylib" _imagingtk.so
你看到里面的@rpath 位了吗?这意味着您在路径上找到的任何一个。这对蟒蛇很有用。 _imagingtk.so 库中的链接现在如下所示:
(py35)? ~/anaconda/envs/py35/lib/python3.5/site-packages/PIL
calebhattingh $ otool -L _imagingtk.so
_imagingtk.so:
@rpath/libtcl8.5.dylib (compatibility version 8.5.0, current version 8.5.9)
@rpath/libtk8.5.dylib (compatibility version 8.5.0, current version 8.5.9)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
在此之后,您的代码将运行。有人可能应该尝试在上游获取此信息。
附录:python 发行版中的 Tkinter 绑定,即当前活动的 conda env,具有以下链接:
? ~/anaconda/envs/py35/lib/python3.5/lib-dynload
calebhattingh $ otool -L _tkinter.cpython-35m-darwin.so
_tkinter.cpython-35m-darwin.so:
@loader_path/../../libtcl8.5.dylib (compatibility version 8.5.0, current version 8.5.18)
@loader_path/../../libtk8.5.dylib (compatibility version 8.5.0, current version 8.5.18)
/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 111.0.0)
如果您愿意,您可以使用install_name_tool 来代替我上面使用的@loader_path/../../,即@rpath/。这可能也会起作用,甚至可能会更好。