URN Logo
UNIX Resources » Linux » China Linux Forum » Python 编 程 » 19 » [精华] 在c中嵌入python(1)
announcement 声明: 本页内容为中国Linux论坛的内容镜像,文章的版权以及其他所有的相关权利属于中国Linux论坛和相应文章的作者,如果转载,请注明文章来源及相关版权信息。
Resources
China Linux Forum(finished)
Linux Forum(finished)
FreeBSD China(finished)
linuxforum.net
  业界新闻与评论
  自由软件杂谈
  IT 人生
  Linux软件快递
  翻译作坊
  Linux图书与评论
  GNU Emacs/XEmacs
  Linux 中文环境和中文化
  Linux桌面与办公软件
  Linux 多媒体与娱乐版
  自由之窗Mozilla
  笔记本电脑上的Linux
  Gentoo
  Debian 一族
  网络管理技术
  Linux 安装与入门
  WEB服务器和FTP服务器
  域名服务器和邮件服务器
  Linux防火墙和代理服务器应用
  文件及打印服务器
  技术培训与认证
  Linux内核技术
  Linux 嵌入技术
  Linux设备驱动程序
  Linux 集群技术
  LINUX平台数据库
  系统和网络安全
  CPU 与 编译器
  系统计算研究所专栏
  Linux下的GUI软件开发
  C/C++编程版
  PHP 技 术
  Java&jsp技术
  Shell编程技术
  Perl 编 程
  Python 编 程
  XML/Web Service 技术
  永远的Unix
  FreeBSD世界
   
[精华] 在c中嵌入python(1)
[精华] 在c中嵌入python(1) - rings [2004-04-18 14:04 | 6,762 byte(s)]
 
Re: 在c中嵌入python(1) - hoxide [2004-05-13 20:13 | 159 byte(s)]
 
Re: 在c中嵌入python(1) - limodou [2004-05-14 13:22 | 217 byte(s)]
 
Re: 在c中嵌入python(1) - gxcooo [2004-05-14 19:55 | 44 byte(s)]
 
Re: 在c中嵌入python(1) - oyster [2004-05-14 23:53 | 100 byte(s)]
 
Re: 在c中嵌入python(1) - rings [2004-05-13 20:26 | 23 byte(s)]
 
Subject: [精华] 在c中嵌入python(1)
Author: rings    Posted: 2004-04-18 14:04    Length: 6,762 byte(s)
[Original] [Print] [Top]
在c中嵌入python

我们可以在c中嵌入python的调用。来执行python的命令或者脚本。我们先看
一个最简单的例子

#include <Python.h>
int
main(int argc, char *argv[])
{
Py_Initialize();
PyRun_SimpleString("from time import time,ctime "
"print 'Today is',ctime(time()) ");
Py_Finalize();
return 0;
}
这段c代码的执行其实就是调用python的:

"from time import time,ctime"
print 'Today is',ctime(time())

所有的python调用都必须在Py_Initialize()和Py_Finalize()之间。这个
好比在c中调用汇编一样
__asm // __asm block
{
mov eax, 01h
int 10h
}
PyRun_SimpleString是python的一个api,他的原型是
int PyRun_SimpleString( char *command)
他在__main__模块中来执行command。这个是最简单的执行python
调用的一种方式。

在嵌入python的调用中,其实我们主要是先把一些数据从c的表示形式转化成
python的表示形式。 比如, PyString_FromString,就是将一个c的字符串转化
成python的表示。然后调用python的API, 因为python的api的参数都是python的
表示形式。最后, 把python的调用结果转化成c的表示形式

在看一个复杂的调用。在python中,我们想调用math 模块的sqrt来做开方运算。一般
都要这么几个步骤。
1。 导入math模块
import math
2. 调用sqrt
>>>math.sqrt(16)
4.0

如果我们想在c中调用,也需要同样的步骤,不过只是我们是用c来做的。而且要加上
数据类型的转换。看一个例子。他其实就是做我们在python的工作
如果这个程序编译成test.exe, 那么他的调用形式应该是:


test.exe math sqrt 16

////////////////////////////////////////////////////////////
#include <Python.h>

int
main(int argc, char *argv[])
{
PyObject *pName, *pModule, *pDict, *pFunc;
PyObject *pArgs, *pValue;
int i;

//先检查参数的个数。第一个参数是这个程序的名字, 在这里是vtest.exe
//第二个参数是模块的名字,第三个参数是这个模块里函数的名字
//后面的参数是调用这个函数的参数
//
if (argc < 3) {
fprintf(stderr,"Usage: call pythonfile funcname [args] ");
return 1;
}

Py_Initialize();
//获得第二个参数。argv[1]。他是模块的名字
pName = PyString_FromString(argv[1]);
/* Error checking of pName left out */

//导入模块, 例如import math. pName是传入的第二个参数。
pModule = PyImport_Import(pName);
Py_DECREF(pName);

if (pModule != NULL) {
//得到模块的__dict__。 相当于在python里调用
//math.__dict__
pDict = PyModule_GetDict(pModule);
/* pDict is a borrowed reference */

//在这个字典里找到我们要找的函数名字。函数名字是argv[2]
//在python里,相当于math.__dict__["sqrt"], 他返回的是个
//函数对象

pFunc = PyDict_GetItemString(pDict, argv[2]);
/* pFun: Borrowed reference */

//解析剩下的参数。这些参数是要传给我们要调用函数的参数。
//他们的数目是不定的。所以把他们存入到一个列表里
if (pFunc && PyCallable_Check(pFunc)) {
pArgs = PyTuple_New(argc - 3); //构造一个Tuple, 长度是argc - 3
for (i = 0; i < argc - 3; ++i) { //做循环把剩余的参数设置到这个tuplp里
pValue = PyInt_FromLong(atoi(argv[i + 3])); //把c的类型转换成python的类型
if (!pValue) {
Py_DECREF(pArgs);
Py_DECREF(pModule);
fprintf(stderr, "Cannot convert argument ");
return 1;
}
/* pValue reference stolen here: */
PyTuple_SetItem(pArgs, i, pValue); //设置这个值到tuple里。
}
pValue = PyObject_CallObject(pFunc, pArgs); //调用函数pFunc是函数名字, pArgs 是参数。
Py_DECREF(pArgs);
if (pValue != NULL) { //调用成功,打印一条信息
printf("Result of call: %ld ", PyInt_AsLong(pValue));
Py_DECREF(pValue);
}
else {
Py_DECREF(pModule); //没有调用成功,打印错误的原因
PyErr_Print();
fprintf(stderr,"Call failed ");
return 1;
}
/* pDict and pFunc are borrowed and must not be Py_DECREF-ed */
}
else {
if (PyErr_Occurred())//检查到是否有错误发生
PyErr_Print();
fprintf(stderr, "Cannot find function "%s" ", argv[2]);
}
Py_DECREF(pModule);
}
else {
PyErr_Print();
fprintf(stderr, "Failed to load "%s" ", argv[1]);
return 1;
}
Py_Finalize();
return 0;
}

以test.exe math sqrt 16 作为一个例子
整个的流程是这样的。
1. 解析参数, test.exe 是argv[0]. math 是argv[1] sqrt 是argv[2]
剩下的参数个数是argc -3. argc 在这里是4, 剩下一个参数。
构造一个tuple, 把16设置到这个tuple中。

2.调用sqrt(16). 使用PyObject_CallObject。 第一个参数是找个函数对象,
第二个是存入剩余参数的tuple。

在python里,这段c代码相当于执行:
1. import math. --------------> pModule = PyImport_Import("math");
2. math.__dict__--------------> pDict = PyModule_GetDict(pModule);
3. math.__dict__["sqrt"]------> pFunc = PyDict_GetItemString(pDict, "sqrt");
4. math.__dict__["sqrt"](16)--->PyObject_CallObject(pFunc, 16)

找个是主要的流程,剩余的代码是错误检查和引用计数的处理。两个c的例子都可以在
python的文档里找到, 他们位于Embedding Python in Another Application



[Original] [Print] [Top]
Subject: Re: 在c中嵌入python(1)
Author: hoxide    Posted: 2004-05-13 20:13    Length: 159 byte(s)
[Original] [Print] [Top]
在python中嵌入c也不错,但我只在FreeBSD平台上实现了,win2k上需要VC6.0的支持,但我安装了VC6.0仍然不能完成编译.

总结是hack python还是到开源平台吧.
----
其实我很菜。
[Original] [Print] [Top]
Subject: Re: 在c中嵌入python(1)
Author: rings    Posted: 2004-05-13 20:26    Length: 23 byte(s)
[Original] [Print] [Top]
我用vc6编译的都很好的。
[Original] [Print] [Top]
Subject: Re: 在c中嵌入python(1)
Author: limodou    Posted: 2004-05-14 13:22    Length: 217 byte(s)
[Original] [Print] [Top]
在windows上使用gcc我有一贴文章可以参考一下:
http://limodou.donews.net/limodou/posts/11800.aspx
----
我的Blog(http://limodou.donews.net/limodou)
[Original] [Print] [Top]
Subject: Re: 在c中嵌入python(1)
Author: gxcooo    Posted: 2004-05-14 19:55    Length: 44 byte(s)
[Original] [Print] [Top]
结合swig扩展嵌入的python就更强大了
----
[Original] [Print] [Top]
Subject: Re: 在c中嵌入python(1)
Author: oyster    Posted: 2004-05-14 23:53    Length: 100 byte(s)
[Original] [Print] [Top]
www.blender.org的代码如何?
[Original] [Print] [Top]
« Previous thread
《Python与Tkinter编程》的源代码
Python 编 程
19
Next thread »
scipy中plot错误,好象是wxPython的问题?
     

Copyright © 2007 UNIX Resources Network, All Rights Reserved.      About URN | Privacy & Legal | Help | Contact us
备案序号: 京ICP备05006143    webmaster: webmaster@unixresources.net
This page created on 2008-07-17 04:11:41, cost 0.043689966201782 ms.