OS X中PyDev与外部库的困难

4 投票
3 回答
4391 浏览
提问于 2025-04-15 22:59

我在我的Eclipse(3.5.1)上成功安装了最新版本的PyDev,系统是OS X 10.6.3,使用的是python 2.6.1。
不过,我在让已安装的库正常工作时遇到了一些麻烦。
比如,我想使用cx_Oracle库,这个库在用python解释器或者用简单的文本编辑器写的脚本中运行得很好。
但是在Eclipse里我却无法让它正常工作:我有这么一小段代码:

import cx_Oracle
conn = cx_Oracle.connect(CONN_STRING)
sql = "select field from mytable"
cursor = conn.cursor()
cursor.execute(sql)
for row in cursor:
    field = row[0]
    print field

当我从Eclipse执行这段代码时,出现了以下错误:

import cx_Oracle
  File "build/bdist.macosx-10.6-universal/egg/cx_Oracle.py", line 7, in <module>
  File "build/bdist.macosx-10.6-universal/egg/cx_Oracle.py", line 6, in __bootstrap__
ImportError: dlopen(/Users/dave/.python-eggs/cx_Oracle-5.0.3-py2.6-macosx-10.6-universal.egg-tmp/cx_Oracle.so, 2): Library not loaded: /b/227/rdbms/lib/libclntsh.dylib.10.1
  Referenced from: /Users/dave/.python-eggs/cx_Oracle-5.0.3-py2.6-macosx-10.6-universal.egg-tmp/cx_Oracle.so
  Reason: no suitable image found.  Did find:
    /Users/dave/lib/libclntsh.dylib.10.1: mach-o, but wrong architecture

同样的代码在python命令行中运行得很好。

我在Eclipse的设置里配置了解释器,路径是:首选项 -> PyDev -> 解释器 - Python,使用了自动配置选项,并选择了所有找到的库。

我到底哪里做错了呢?

编辑:从命令行启动

file /Users/dave/.python-eggs/cx_Oracle-5.0.3-py2.6-macosx-10.6-universal.egg-tmp/cx_Oracle.so

会显示这个:

/Users/dave/.python-eggs/cx_Oracle-5.0.3-py2.6-macosx-10.6-universal.egg-tmp/cx_Oracle.so: Mach-O universal binary with 3 architectures
/Users/dave/.python-eggs/cx_Oracle-5.0.3-py2.6-macosx-10.6-universal.egg-tmp/cx_Oracle.so (for architecture i386):  Mach-O bundle i386
/Users/dave/.python-eggs/cx_Oracle-5.0.3-py2.6-macosx-10.6-universal.egg-tmp/cx_Oracle.so (for architecture ppc7400):   Mach-O bundle ppc
/Users/dave/.python-eggs/cx_Oracle-5.0.3-py2.6-macosx-10.6-universal.egg-tmp/cx_Oracle.so (for architecture x86_64):    Mach-O 64-bit bundle x86_64

3 个回答

0

我之前在使用cx_Oracle和Eclipse时遇到了类似的问题:在终端里一切正常,但在Eclipse里却出现了no suitable image error的错误。这绝对是个二进制兼容性的问题(对我来说,是32位和64位的问题)。

JulesLt提供了解决方案,他提到了一个开发者网站。我使用了那个文档中提到的lipo选项,操作起来非常简单。因为我们有开发者同时使用32位和64位的安装版本,所以我们已经为每种版本准备了instantclient(这里没有PPC机器)。

假设有三个文件夹:instantclient_32instantclient_64instantclient_fat——其中instantclient_fat只是32位或64位文件夹的一个副本,接下来可以按照以下步骤操作:

cd instantclient_32 ; for f in `ls *dylib* genezi sqlplus` ; do lipo -create $f ../instantclient_64/$f -output ../instantclient_fat/$f ; done

以上操作会用fat二进制文件覆盖instantclient_fat中的相关可执行文件。完成后,使用这个instantclient库来构建cx_Oracle,就大功告成了。

感谢JulesLt……这解决了很多烦人的问题。

1

不知道你是否已经解决了这个问题,但从评论来看,似乎你遇到了32位和64位的兼容性问题。

cx_Oracle.so是一个通用的二进制文件,里面包含了PPC、32位和64位的Intel版本,但从你的评论来看,你的libclntsh.dylib.10.1的结果和我的不一样。

file libclntsh.dylib.10.1
libclntsh.dylib.10.1: Mach-O 64-bit dynamically linked shared library x86_64

不过,如果我对32位客户端运行相同的命令,我得到的结果和你是一样的(我把它放在一个单独的文件夹里)。

file libclntsh.dylib.10.1
libclntsh.dylib.10.1: Mach-O dynamically linked shared library i386

我猜测,当你从命令行运行时,可能使用了不同的路径,找到了合适的libclntsh,或者通过Eclipse运行时,导致它以与命令行相反的模式运行。

解决方案是,从Oracle下载32位和64位的Instant Client,但放在不同名字的文件夹里,然后通过链接来控制使用哪个版本。

如果你觉得有挑战性,可以做Oracle没有做到的事情,把这两个dylib合并成一个通用的二进制文件。

http://developer.apple.com/mac/library/technotes/tn2005/tn2137.html#TNTAG3
5

在Eclipse里,找到‘PyDev’选项,然后在‘解释器 - Python’(或者你用的其他解释器)下设置以下‘环境变量’。

  1. ORACLE_HOME=[你的安装路径]/instantclient_10_2
  2. LD_LIBRARY_PATH=$ORACLE_HOME
  3. DYLD_LIBRARY_PATH=$ORACLE_HOME

这样设置后对我有效。

撰写回答