pyrex,ctypes 两种有什么区别?

20 views
Skip to first unread message

feihu

unread,
Dec 5, 2006, 9:29:54 AM12/5/06
to python-...@lists.python.cn, pyth...@googlegroups.com
现在我已经有一些c写的lib(有源码的),想在python里调用,应该使用什么?

看大家说的比较多的是都是c、c++来调用python。而用python来调用c的,或者c来
写python的扩展的,文档多是说可以这么做?但具体的步骤都很少,或者是简单的
hello world程序。
--
feihu <feihu...@gmail.com>

yi huang

unread,
Dec 5, 2006, 9:38:38 AM12/5/06
to pyth...@googlegroups.com
现在我已经有一些c写的lib(有源码的),想在python里
调用,应该使用什么?

看大家说的比较多的是都是c、c++来调用python。而用python来调用c的,或者c来
写python的扩展的,文档多是说可以这么做?但具体的步骤都很少,或者是简单的
hello world程序。

虽然都没怎么用过,不过据我的了解,ctypes只是主要是用来访问共享库的吧,为自己的有源码的库提供python接口,当然是选择pyrex了。
pyrex本身的文档还算完整的吧。


--
http://codeplayer.blogspot.com/

大熊

unread,
Dec 5, 2006, 9:48:50 AM12/5/06
to pyth...@googlegroups.com
显然你的文档看得不仔细,在python的文档有一章"Extending and Embedding ",就是专门讲这方面的,而且也有简单的例子

pyrex,
A Python-like language for writing extension modules, 就是python式的语言来写python扩展
ctypes 则是在python直接调用dll函数,另外还有comtypes,甚至可以用来调用dll中的com对象

你现有的是lib或源码,那应该需要写
扩展了;如果可以编译成dll的话,也可以试一试ctypes,python2.5中这个以是标准库了


在06-12-5,feihu <feihu...@gmail.com> 写道:



--
茫茫人海,你是我的最爱

Zhuo Wei

unread,
Dec 5, 2006, 8:14:23 PM12/5/06
to pyth...@googlegroups.com, python-...@lists.python.cn
使用pyrex,如果需要在Python代码总访问C代码的Struct和Union,比较麻烦。
参考:http://lists.copyleft.no/pipermail/pyrex/2005-July/001277.html
所以建议你使用ctypes,文档见python2.5标准库文档

以下是一个在linux,调用GTK的hello world代码,仅供参考。

from ctypes import *
libgtk = CDLL("libgtk-x11-2.0.so")
libgobject = CDLL(" libgobject-2.0.so")

GTK_WINDOW_TOPLEVEL = 0
GTK_WINDOW_POPUP = 1

gtk_init = libgtk.gtk_init
gtk_window_new = libgtk.gtk_window_new
gtk_widget_show = libgtk.gtk_widget_show
gtk_button_new_with_label = libgtk.gtk_button_new_with_label

g_signal_connect = libgobject.g_signal_connect_data
g_signal_connect_closure = libgobject.g_signal_connect_closure
g_cclosure_new = libgobject.g_cclosure_new

CALLBACK = CFUNCTYPE(c_void_p)

def destroy():
    libgtk.gtk_main_quit()

def hello():
    libgtk.g_print("hello world!\n")


gtk_init(None, None)
window = gtk_window_new(c_int(GTK_WINDOW_TOPLEVEL))
libgtk.gtk_container_set_border_width (window, 10);
c = g_cclosure_new(CALLBACK(destroy), c_void_p(0) , c_int(0))
g_signal_connect(window, create_string_buffer("destroy"), CALLBACK(destroy), None)

button = gtk_button_new_with_label ("Hello World");
g_signal_connect(button, create_string_buffer("clicked"), CALLBACK(hello), None)

libgtk.gtk_container_add(window, button);

gtk_widget_show(button)
gtk_widget_show(window)
libgtk.gtk_main()



在06-12-5,feihu <feihu...@gmail.com> 写道:

feihu

unread,
Dec 5, 2006, 10:17:22 PM12/5/06
to pyth...@googlegroups.com
坐以论道,起而行之,先写一个简单但完整的例子来测试pyrex调用已有lib库法。
环境:ubuntu 6.06,python 2.4.3
参考:http://ldots.org/pyrex-guide/

1,先生成简单的lib:
=>vi test.h
int tadd(int a, int b);

=>vi test.c
#include "test.h"
int tadd(int a, int b)
{
return a+b;
};

=>gcc -c test.c
生成test.o
=>ar -rsv libtest.a test.o
生成了 libtest.a 静态库

2,我们测试一下这个lib可以用吗?
=>vi ttest.c
#include <stdio.h>
#include "test.h"
void main(int argc, void * argv[])
{
int c=1;
c = tadd(1, 4);
printf("c = %d \r\n", c);
}

=>gcc ttest.c -ltest -L.
生成了a.out
./a.out 结果是:
c = 5

证明我们的lib库是可以正常工作的

3,写一个python的模块td,调用它libtest里的tadd()函数

写一个pyx,
=>vi td.pyx
cdef extern from "test.h":
int tadd(int i, int j)

def tdadd(int i, int j):
cdef int c
c=tadd(i, j)
return c

就在这行调用的:c=tadd(i, j)了。

编译:
=>pyrexc td.pyx
生成 td.c
=>gcc -c -fPIC -I/usr/include/python2.4/ td.c
生成td.c
=>gcc -shared td.o -ltest -L. -o td.so
生成了td.so。这个就是python可以用的模块so了

安装:
=>vi setup.py
from distutils.core import setup
from distutils.extension import Extension
from Pyrex.Distutils import build_ext
setup(
name = "PyrexGuide",
ext_modules=[
Extension("td", ["td.pyx"], libraries = ["test"])
],
cmdclass = {'build_ext': build_ext}
)


=>python setup.py build_ext --inplace

测试:
>>> import td
>>> dir(td)
['__builtins__', '__doc__', '__file__', '__name__', 'tdadd']
>>> td.tdadd(1,2)
3

呵呵,OK了。

等会再试一试ctypes

> 使用pyrex,如果需要在Python代码总访问C代码的Struct和Union,比较麻烦。
> 参考:http://lists.copyleft.no/pipermail/pyrex/2005-July/001277.html
> 所以建议你使用ctypes,文档见python2.5标准库文档

--
feihu <feihu...@gmail.com>

Zoom.Quiet

unread,
Dec 5, 2006, 10:20:11 PM12/5/06
to pyth...@googlegroups.com
两者思路完全不同哪!
Pyrex 是自动将Python 脚本转化为可编译的C 代码,以便高效执行和被C程序调用;
ctypes 则是为C程序员组织的约定,以便将C程序合理暴露出必要接口给Python 以便Python 脚本来调用C 程序;


--
'''Time is unimportant, only life important!
blog@ http://blog.zoomquiet.org/pyblosxom/
wiki@ http://wiki.woodpecker.org.cn/moin/ZoomQuiet
douban@ http://www.douban.com/people/zoomq/
____________________________________
Please use OpenOffice.org to replace M$ office.
http://zh.openoffice.org
Please use 7-zip to replace WinRAR/WinZip.
http://7-zip.org/zh-cn/
You can get the truely Freedom from software.
'''

limodou

unread,
Dec 5, 2006, 10:33:33 PM12/5/06
to pyth...@googlegroups.com
On 12/6/06, feihu <feihu...@gmail.com> wrote:
>
写得好,收藏之。

--
I like python!
UliPad <<The Python Editor>>: http://wiki.woodpecker.org.cn/moin/UliPad
My Blog: http://www.donews.net/limodou

yi huang

unread,
Dec 5, 2006, 11:08:44 PM12/5/06
to pyth...@googlegroups.com
Pyrex 是自动将Python 脚本转化为可编译的C 代码,以便高效执行和被C程序调用;

我觉得 Pyrex 主要是用来为 c 库 提供一个 pythinic 的接口,而非优化python程序。

--
http://codeplayer.blogspot.com/

Zoom.Quiet

unread,
Dec 5, 2006, 11:42:12 PM12/5/06
to pyth...@googlegroups.com

已经有两篇 混合编程的我们自个儿的教程了!
http://wiki.woodpecker.org.cn/moin/Pyrex

哈哈哈!大家努力,相互分享学习成果哪!

> --
> I like python!
> UliPad <<The Python Editor>>: http://wiki.woodpecker.org.cn/moin/UliPad
> My Blog: http://www.donews.net/limodou
>

feihu

unread,
Dec 6, 2006, 1:05:55 AM12/6/06
to pyth...@googlegroups.com, python-...@lists.python.cn
继续测试ctypes的用法:
下载ctypes,安装好。

先把刚才的静态test.o编译成动态链接库:
=>gcc -shared test.o -o test.so

然后=>python
>>> from ctypes import *
>>> libt = CDLL("test.so")
>>> libt
<CDLL 'test.so', handle 81ae8b0 at b7de004c>
>>> a= libt.tadd(1, 3)
>>> print a
4

哇哇,好像更加方便了。

总结:
两者都是扩展了python调用外部lib途径。好像pyrex更强调调用静态的lib,而且是把lib编译成python自己原生的module。
为了做到这个,除了有lib的.a文件外,必须要有lib的.h文件。
ctypes则是显示的调用动态的lib,只要有lib的.so,.dll就可以,目前ctypes已经成为2.5的内部module。
而pyrex还有一个比较重要特点就是可以用类c的语法写python的moduele。

比较同意这个观点:


> 我觉得 Pyrex 主要是用来为 c 库 提供一个 pythinic 的接口,而非优化python程序。

目前的例子非常简单,复杂情况下的调用有可能出现的问题都还没有碰到。Zoom给的文章里说到的复杂的结构,联合的情况
也还没有尝试。

想到要调用的lib的线程,指针,内存块操作,就有点头痛。
初步还是决定采用ctypes的方式,工作量上要少写一点东西,至少调试的时候也更直接一点。

一切都根据实际情况来做吧,要试错。

--
feihu <feihu...@gmail.com>

Zoom.Quiet

unread,
Dec 6, 2006, 1:18:32 AM12/6/06
to pyth...@googlegroups.com
On 12/6/06, feihu <feihu...@gmail.com> wrote:
>
> 继续测试ctypes的用法:
> 下载ctypes,安装好。
>
收藏!合并到你上一邮件的文章
http://wiki.woodpecker.org.cn/moin/FeihuTryPyrex

刘鑫

unread,
Dec 6, 2006, 1:42:44 AM12/6/06
to python-...@lists.python.cn
如果说对C++语言的封装,Boost::Python绝对是非常强大的。当然Boost更适合"使用Python的C++程序员",对"想要使用C++的Python程序员",Boost可能稍有点艰深。

2006/12/6, Jacob Fan <ja...@exoweb.net>:
feihu wrote:
> 现在我已经有一些c写的lib(有源码的),想在python里调用,应该使用什么?
>
> 看大家说的比较多的是都是c、c++来调用python。而用python来调用c的,或者c来
> 写python的扩展的,文档多是说可以这么做?但具体的步骤都很少,或者是简单的
> hello world程序。
>
包装现成的c lib, 最简单的方法, 用swig包装一下就搞定了.
看这里, http://www.swig.org/tutorial.html
_______________________________________________
python-chinese
Post: send python-...@lists.python.cn
Subscribe: send subscribe to python-chin...@lists.python.cn
Unsubscribe: send unsubscribe to  python-chin...@lists.python.cn
Detail Info: http://python.cn/mailman/listinfo/python-chinese



--
欢迎访问:
http://blog.csdn.net/ccat

刘鑫
March.Liu

刘鑫

unread,
Dec 6, 2006, 3:06:56 AM12/6/06
to python-...@lists.python.cn
对啊,而且Boost对于习惯了纯C代码的人来说,恐怕编译速度太慢了:P

2006/12/6, Jacob Fan <ja...@exoweb.net>:
刘鑫 wrote:
> 如果说对C++语言的封装,Boost::Python绝对是非常强大的。当然Boost更适合"
> 使用Python的C++程序员",对"想要使用C++的Python程序员",Boost可能稍有点
> 艰深。
>
对于想要使用c lib的Python程序员Boost::Python就更用不上了. 而且如果编译时
出点奇怪的C++的错误, 会让Python程序员头大.
> 2006/12/6, Jacob Fan <ja...@exoweb.net <mailto:ja...@exoweb.net>>:

>
>     feihu wrote:
>     > 现在我已经有一些c写的lib(有源码的),想在python里调用,应该使用
>     什么?
>     >
>     > 看大家说的比较多的是都是c、c++来调用python。而用python来调用c
>     的,或者c来
>     > 写python的扩展的,文档多是说可以这么做?但具体的步骤都很少,或者
>     是简单的
>     > hello world程序。
>     >
>     包装现成的c lib, 最简单的方法, 用swig包装一下就搞定了.
>     看这里, http://www.swig.org/tutorial.html
>     _______________________________________________
>

_______________________________________________
python-chinese
Post: send python-...@lists.python.cn
Subscribe: send subscribe to python-chin...@lists.python.cn
Unsubscribe: send unsubscribe to  python-chin...@lists.python.cn
Detail Info: http://python.cn/mailman/listinfo/python-chinese

刘鑫

unread,
Dec 6, 2006, 3:48:52 AM12/6/06
to python-...@lists.python.cn
对于C++程序员,Boost应该是很好的选择吧:),我从Python库开始,再到shared_ptr,再到lambda,再到string,Boost里的东西用到的越来越多,呵呵。很多以前你用的库,说不定都可以统一转到这个Boost里了。

2006/12/6, 苏亚 <su19...@163.com >:
刘鑫 写道:
> 对啊,而且Boost对于习惯了纯C代码的人来说,恐怕编译速度太慢了:P
>
> 2006/12/6, Jacob Fan < ja...@exoweb.net <mailto:ja...@exoweb.net>>:

>
>     刘鑫 wrote:
>     > 如果说对C++语言的封装,Boost::Python绝对是非常强大的。当然Boost
>     更适合"
>     > 使用Python的C++程序员",对"想要使用C++的Python程序员",Boost可能
>     稍有点
>     > 艰深。
>     >
>     对于想要使用c lib的Python程序员Boost::Python就更用不上了. 而且如果
>     编译时
>     出点奇怪的C++的错误, 会让Python程序员头大.
>     > 2006/12/6, Jacob Fan <ja...@exoweb.net <mailto:ja...@exoweb.net>
>     <mailto: ja...@exoweb.net <mailto:ja...@exoweb.net>>>:

>     >
>     > feihu wrote:
>     > > 现在我已经有一些c写的lib(有源码的),想在python里调用,应该使用
>     > 什么?
>     > >
>     > > 看大家说的比较多的是都是c、c++来调用python。而用python来调用c
>     > 的,或者c来
>
就是,前一段时间研究过boost::python,是挺好用,但就像前面说的,我是希
望用python的c++程序员,而且是正在用n个c++库的程序员,想要转行真的好难呀

_______________________________________________
python-chinese
Post: send python-...@lists.python.cn
Subscribe: send subscribe to python-chin...@lists.python.cn
Unsubscribe: send unsubscribe to  python-chin...@lists.python.cn
Detail Info: http://python.cn/mailman/listinfo/python-chinese
Reply all
Reply to author
Forward
0 new messages