Acceder a constantes de bibliotecas C con Python usando ctypes
2010-10-09 17:32:04 GMT
Hola lista,
Estoy trasteando un poco con la biblioteca ctypes para usar bibliotecas compartidas escritas en C desde Python.
No he tenido problemas hasta ahora para usarla, salvo cuando necesito acceder a constantes que posea la biblioteca.
Por ejemplo, usando la biblioteca de MPI en C (ya se que existen implementaciones en python, pero quiero utilizarla nativamente) necesito acceder a
una constanet llamada MPI_COMM_WORLD
En la documentación oficial: http://docs.python.org/library/ctypes.html#accessing-values-exported-from-dlls
solo se muestra un pequeño ejemplo para acceder a una constante, pero es de la propia python C api y no he sabido trasladar el ejemplo o como usarlo para otra biblioteca.
Este es mi código de ejemplo (tambien en pastebin: http://pastebin.com/zcmtQ4G6 ):
#!/usr/bin/python
import sys
try:
from ctypes import CDLL, pythonapi, c_int, POINTER, c_char_p, byref, RTLD_GLOBAL
from ctypes.util import find_library
except ImportError:
print 'ERROR! La libreria *ctypes* para Python no esta disponible!'
sys.exit(-1)
libc = CDLL('libc.so.6')
print libc._handle, libc._name
f = pythonapi.Py_GetArgcArgv
argc = c_int()
argv = POINTER(c_char_p)()
f(byref(argc), byref(argv))
mpi = CDLL(find_library('mpi'), RTLD_GLOBAL)
print mpi._handle, mpi._name
myrank = c_int();
nprocs = c_int();
opt_flag = c_int.in_dll(pythonapi, "MPI_COMM_WORLD") # Aqui falla al acceder a MPI_COMM_WORLD
#mpi.MPI_Comm_size(mpi.MPI_COMM_WORLD, byref(nprocs)); # Lo necesito aqui, pero no funciona MPI_COMM_WORLD
libc.printf("Hello from processor %d of %d\n", myrank, nprocs);
mpi.MPI_Finalize()
--------
En teoria se accede con el método in_dll() pero no consigo extraer el valor y me falla con un:
Traceback (most recent call last):
File "memory.py", line 36, in <module>
opt_flag = c_int.in_dll(pythonapi, "MPI_COMM_WORLD")
ValueError: python: undefined symbol: MPI_COMM_WORLD
Espero vuestra ayuda.
Saludos
--
Blog: www.shakaran.net
Tivion: un simple reproductor de canales streaming de TV www.shakaran.net/blog/tivion
Mi juego de rol online: www.apogeus.es & www.apogeus.es/ao
Hosting económico y profesional: www.quijost.com
<div><p>Hola lista,<br><br>Estoy trasteando un poco con la biblioteca ctypes para usar bibliotecas compartidas escritas en C desde Python.<br><br>No he tenido problemas hasta ahora para usarla, salvo cuando necesito acceder a constantes que posea la biblioteca.<br><br>Por ejemplo, usando la biblioteca de MPI en C (ya se que existen implementaciones en python, pero quiero utilizarla nativamente) necesito acceder a<br>una constanet llamada MPI_COMM_WORLD<br><br>En la documentación oficial: <a href="http://docs.python.org/library/ctypes.html#accessing-values-exported-from-dlls">http://docs.python.org/library/ctypes.html#accessing-values-exported-from-dlls</a><br> solo se muestra un pequeño ejemplo para acceder a una constante, pero es de la propia python C api y no he sabido trasladar el ejemplo o como usarlo para otra biblioteca.<br><br>Este es mi código de ejemplo (tambien en pastebin: <a href="http://pastebin.com/zcmtQ4G6">http://pastebin.com/zcmtQ4G6</a> ):<br> #!/usr/bin/python<br><br>import sys<br><br>try:<br> from ctypes import CDLL, pythonapi, c_int, POINTER, c_char_p, byref, RTLD_GLOBAL<br> from ctypes.util import find_library<br>except ImportError:<br> print 'ERROR! La libreria *ctypes* para Python no esta disponible!'<br> sys.exit(-1)<br><br>libc = CDLL('libc.so.6')<br><br>print libc._handle, libc._name<br><br>f = pythonapi.Py_GetArgcArgv<br>argc = c_int()<br>argv = POINTER(c_char_p)()<br>f(byref(argc), byref(argv))<br><br>mpi = CDLL(find_library('mpi'), RTLD_GLOBAL)<br> print mpi._handle, mpi._name<br><br>myrank = c_int();<br>nprocs = c_int();<br><br>opt_flag = c_int.in_dll(pythonapi, "MPI_COMM_WORLD") # Aqui falla al acceder a MPI_COMM_WORLD<br><br>#mpi.MPI_Comm_size(mpi.MPI_COMM_WORLD, byref(nprocs)); # Lo necesito aqui, pero no funciona MPI_COMM_WORLD<br><br>libc.printf("Hello from processor %d of %d\n", myrank, nprocs);<br><br>mpi.MPI_Finalize() <br clear="all"><br>--------<br><br>En teoria se accede con el método in_dll() pero no consigo extraer el valor y me falla con un:<br> Traceback (most recent call last):<br> File "memory.py", line 36, in <module><br> opt_flag = c_int.in_dll(pythonapi, "MPI_COMM_WORLD")<br>ValueError: python: undefined symbol: MPI_COMM_WORLD<br><br>Espero vuestra ayuda.<br><br>Saludos<br><br>-- <br>Blog: <a href="http://www.shakaran.net" target="_blank">www.shakaran.net</a><br>Tivion: un simple reproductor de canales streaming de TV <a href="http://www.shakaran.net/blog/tivion" target="_blank">www.shakaran.net/blog/tivion</a><br>Mi juego de rol online: <a href="http://www.apogeus.es" target="_blank">www.apogeus.es</a> & <a href="http://www.apogeus.es/ao" target="_blank">www.apogeus.es/ao</a><br>Hosting económico y profesional: <a href="http://www.quijost.com" target="_blank">www.quijost.com</a><br></p></div>
RSS Feed