2011-08-15 18 views
6

Estoy caminando por la documentación de Cython y construyendo cada una de las aplicaciones de ejemplo. Estoy un poco atrapado en el uso de Bibliotecas C Después de crear con éxito el archivo .so e intentar importarlo en un archivo python denominado test.py, se produce el siguiente error.¿Cuál es el significado de este ImportError al importar un archivo .so generado por Cython?

$ python3.2 test.py 
Traceback (most recent call last): 
    File "test.py", line 12, in <module> 
    from queue import Queue 
ImportError: dlopen(/Users/jeremy/Development/labs/python/cython_lib_wrapper/queue.so, 2): Symbol not found: _queue_free 
    Referenced from: /Users/jeremy/Development/labs/python/cython_lib_wrapper/queue.so 
    Expected in: flat namespace 
in /Users/jeremy/Development/labs/python/cython_lib_wrapper/queue.so 

El archivo .so se encuentra justo al lado del archivo test.py. Por lo tanto, parece que debería ser encontrado. Esto está ejecutando la última versión de Cython, con Python 3.2 en un OSX 10.6.

¿Algún conocimiento? salida añadiendo "nm" -

Editar - la adición de construir el mando y la salida

$ python3.2 setup.py build_ext --inplace 
running build_ext 
cythoning queue.pyx to queue.c 
building 'queue' extension 
gcc-4.2 -fno-strict-aliasing -fno-common -dynamic -DNDEBUG -g -O3 -isysroot /Developer/SDKs/MacOSX10.6.sdk -arch i386 -arch x86_64 -isysroot /Developer/SDKs/MacOSX10.6.sdk -I/Library/Frameworks/Python.framework/Versions/3.2/include/python3.2m -c queue.c -o build/temp.macosx-10.6-intel-3.2/queue.o 
    queue.c: In function ‘__pyx_f_5queue_5Queue_append’: 
    queue.c:627: warning: cast to pointer from integer of different size 
    queue.c: In function ‘__pyx_f_5queue_5Queue_extend’: 
    queue.c:740: warning: cast to pointer from integer of different size 
    queue.c: In function ‘__pyx_f_5queue_5Queue_peek’: 
    queue.c:813: warning: cast from pointer to integer of different size 
    queue.c: In function ‘__pyx_f_5queue_5Queue_pop’: 
    queue.c:965: warning: cast from pointer to integer of different size 
    gcc-4.2 -bundle -undefined dynamic_lookup -arch i386 -arch x86_64 -isysroot /Developer/SDKs/MacOSX10.6.sdk -isysroot /Developer/SDKs/MacOSX10.6.sdk -g build/temp.macosx-10.6-intel-3.2/queue.o -o 

Edición 2 - añadiendo "otool" cmd solicitó en el comentario

queue.so: 
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.0) 

Datos 3

U ___stack_chk_fail 
U ___stack_chk_guard 
U _queue_free 
U _queue_is_empty 
U _queue_new 
U _queue_peek_head 
U _queue_pop_head 
U _queue_push_tail 
U dyld_stub_binder 

salidas cmd grep esto:

(undefined) external _queue_free (dynamically looked up) 
+2

Esto parece un problema de enlace. ¿Podría reconstruir e incluir tanto la salida de compilación como el comando utilizado para compilar aquí? – stderr

+0

@Mike Steder Gracias por mirar esto, he agregado el comando de compilación y salida – JeremyFromEarth

+1

Bien, no teniendo mucha suerte de reproducir, así que intentemos un poco más de depuración. Pruebe 'nm queue.so' y vea lo que aparece al lado de _queue_free. También use 'otool -L queue.so' y verifique para ver DYLD_LIBRARY_PATH (' echo $ DYLD_LIBRARY_PATH'). – stderr

Respuesta

5

EDIT:

Ah, usted no mencionó que tenía una dependencia en el código en libcalg. Esas cosas deben compilarse e incluirse cuando construyas la cextension.

Sólo modificar setup.py:

# setup.py 
# ... 
ext_modules = [Extension("queue", ["queue.pyx", "libcalg/queue.c"])] 
# ... 

Podríamos dar un paso atrás y ver si se puede construir un ejemplo muy simple:

He probado los siguientes (3 archivos, myext .pyx, test.py, setup.py) y parece funcionar bien. Por supuesto que estoy en OS X 10.7 por lo que no es exactamente lo mismo que su entorno. Para descartar diferencias, quizás pueda copiarlas y construirlas como un control de cordura.

Contenido de myext.pyx:

# myext.pyx 
def square(x): 
    return x * x 

Contenido de test.py

# test.py 
from myext import square 
print "%d squared is %d"%(4, square(4)) 

Contenido de setup.py:

# setup.py 
from distutils.core import setup 
from distutils.extension import Extension 
from Cython.Distutils import build_ext 

ext_modules = [Extension("myext", ["myext.pyx"])] 

setup(
    name = 'Hello world app', 
    cmdclass = {'build_ext': build_ext}, 
    ext_modules = ext_modules 
) 

construyo en el directorio que contiene estos 3 archivos:

cython_test$ /usr/bin/python setup.py build_ext --inplace 
running build_ext 
cythoning myext.pyx to myext.c 
building 'myext' extension 
creating build 
creating build/temp.macosx-10.7-intel-2.7 
llvm-gcc-4.2 -fno-strict-aliasing -fno-common -dynamic -g -Os -pipe -fno-common -fno-strict-aliasing -fwrapv -mno-fused-madd -DENABLE_DTRACE -DMACOSX -DNDEBUG -Wall -Wstrict-prototypes -Wshorten-64-to-32 -DNDEBUG -g -fwrapv -Os -Wall -Wstrict-prototypes -DENABLE_DTRACE -arch i386 -arch x86_64 -pipe -I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c myext.c -o build/temp.macosx-10.7-intel-2.7/myext.o 
llvm-gcc-4.2 -Wl,-F. -bundle -undefined dynamic_lookup -Wl,-F. -arch i386 -arch x86_64 build/temp.macosx-10.7-intel-2.7/myext.o -o /Users/steder/SO/cython_test/myext.so 

cython_test$ python test.py 
4 squared is 16: 

Mi entorno tiene una salida de otool similar y DYLD_LIBRARY_PATH también está desarmado, pero nm -m muestra el cuadrado como se define.

Específicamente:

00000000000011d0 (__DATA,__data) non-external ___pyx_k__square 
00000000000011e0 (__DATA,__data) non-external ___pyx_mdef_5myext_square 
0000000000001218 (__DATA,__bss) non-external ___pyx_n_s__square 
0000000000000c80 (__TEXT,__text) non-external ___pyx_pf_5myext_square 

Por favor, dar a este un tiro y ver lo que nm -m muestra en su entorno.

+0

Acabo de configurar y construir esto y funciona perfectamente. Veo la misma salida cuando ejecuto "nm". Lo único que tuve que cambiar fue la declaración de impresión porque estoy usando Python 3.2 y tienes que usar parens. – JeremyFromEarth

+1

Interesante ... Lamentablemente, no estoy seguro de qué es diferente con su extensión de cola. ¿Puedes compartir el código? – stderr

+0

¡Realmente aprecio tu ayuda! Los archivos fuente se encuentran aquí: http://whiplax.com/cython_lib_wrapper.zip – JeremyFromEarth

Cuestiones relacionadas