2016-05-22 1 views
1

Я python noob, пытаясь запустить пример в the KmeansRex library from github. Я использую машину ubuntu. Это библиотека, в которой нет файла setup.py. Несмотря на несколько попыток, я не смог запустить пример короткого кода, показанный в файле README на странице github.Установка/загрузка github :: KMeansRex Python library

Чтобы попытаться установить эту библиотеку, я:

git clone https://github.com/michaelchughes/KMeansRex.git 

Тогда я (в соответствии с инструкциями на странице GitHub, просто называя .so файл libkmeansrex64.so вместо libkmeansrex.so как я нахожусь на 64-битной машине):

g++ --shared -o libkmeansrex64.so KMeansRexCore.cpp -I/home/path/to/eigen/ -O3 -DNDEBUG 

/usr/bin/ld: /tmp/ccdmUbg9.o: relocation R_X86_64_32S against `.bss' can not be used when making a shared object; recompile with -fPIC 
/tmp/ccdmUbg9.o: error adding symbols: Bad value 
collect2: error: ld returned 1 exit status 

так что я:

g++ --shared -o libkmeansrex64.so KMeansRexCore.cpp -I/home/path/to/eigen/ -O3 -fpic -DNDEBUG 

(и это компилируется без ошибок). Тогда я:

cd KMeansRex/ 

Тогда я:

python 

Я следую инструкциям на GitHub для примера:

Python 2.7.11+ (default, Apr 17 2016, 14:00:29) 
[GCC 5.3.1 20160413] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import numpy as np; 

(до сих пор так хорошо). Но тогда, я:

import KMeansRex 

только получить:

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "KMeansRex/__init__.py", line 1, in <module> 
    from KMeansRex import RunKMeans 
    File "KMeansRex/KMeansRex.py", line 30, in <module> 
    lib = ctypes.cdll.LoadLibrary(os.path.join(parentdir,'libkmeansrex64.so')) 
    File "/usr/lib/python2.7/ctypes/__init__.py", line 443, in LoadLibrary 
    return self._dlltype(name) 
    File "/usr/lib/python2.7/ctypes/__init__.py", line 365, in __init__ 
    self._handle = _dlopen(self._name, mode) 
OSError: libkmeansrex64.so: cannot open shared object file: No such file or directory 

Что странно, потому что компилятор сделал производить libkmeansrex64.so:

/KMeansRex$ ls -n 
total 84 
drwxrwxr-x 2 1000 1000 4096 Mai 22 13:24 demonumpyctypes 
drwxrwxr-x 3 1000 1000 4096 Mai 22 14:00 KMeansRex 
-rw-rw-r-- 1 1000 1000 7003 Mai 22 13:24 KMeansRexCore.cpp 
-rw-rw-r-- 1 1000 1000 635 Mai 22 13:24 KMeansRexCore.h 
-rw-rw-r-- 1 1000 1000 2214 Mai 22 13:24 KMeansRex.cpp 
-rwxrwxr-x 1 1000 1000 41792 Mai 22 13:24 libkmeansrex64.so 
-rw-rw-r-- 1 1000 1000 1541 Mai 22 13:24 LICENSE 
-rw-rw-r-- 1 1000 1000 7899 Mai 22 13:24 mersenneTwister2002.c 
-rw-rw-r-- 1 1000 1000 1396 Mai 22 13:24 README 

Edit:

Проблема решена (спасибо пользователю kvorobiev). Так до линии

lib = ctypes.cdll.LoadLibrary(os.path.join(parentdir,'libkmeansrex64.so')) 

Я добавил

print os.path.join(parentdir,'libkmeansrex64.so') 

и незамедлительные печать:

libkmeansrex64.so 

так ясно, что я должен заменить

lib = ctypes.cdll.LoadLibrary(os.path.join(parentdir,'libkmeansrex64.so')) 

By:

lib = ctypes.cdll.LoadLibrary(os.path.join(parentdir,'/path/to/libkmeansrex64.so')) 

Делая это, все работает отлично;)

+0

@renemilk: soory Я не понимаю. Не могли бы вы лучше объяснить, как изменить вызов 'dlopen'? – user189035

+1

Просто откройте файл 'KMeansRex.py' и вставьте' print os.path.join (parentdir, 'libkmeansrex64.so') 'прямо перед' lib = ctypes.cdll.LoadLibrary (os.path.join (parentdir, 'libkmeansrex64 .so ')) 'и добавьте результаты на ваш вопрос – kvorobiev

+0

@kvorobiev: это исправило проблему! Должен ли я удалить этот вопрос? – user189035

ответ

1

Существует проблема с путями в KMeansRex.py.

import os 
... 

curdir = os.path.split(__file__)[0] 
parentdir = os.path.split(curdir)[0] 
... 

В Python3 этот код будет работать правильно, так как __file__ содержит абсолютный путь к файлу.Но в python2 если you aren't inside the part of sys.path that contains the module, you'll get an absolute path. If you are inside the part of sys.path that contains the module, you'll get a relative path.
Вы можете использовать

import os 
... 

curdir = os.path.split(os.path.abspath(__file__))[0] 
parentdir = os.path.split(curdir)[0] 
... 

или просто жёстко абсолютный путь к вашей библиотеке

lib = ctypes.cdll.LoadLibrary('/abs/path/to/lib/libkmeansrex64.so')