我的华硕笔记本电脑开机蓝屏怎么解决方法蓝屏了

C调用Python一个运行时间长的函数,如何实时获取中间结果
来源:csdn
【开发工作如下:
使用Python写了一个FTP客户端组件,支持上传与下载,使用C调用该FTP客户端组件的上传与下载都成功。
C调用上传与下载时,需要实时获取上传或者进度(即已经上传了多少,或者下载了多少),并把这个值复制到某个共享变量中,给其它线程读取使用(只读取)。
但是文件上传与下载的部分全是在Python中写的,进度也只有Python才能知道。
使用Python的线程机制,貌似也不能成功。
请问各位大神,谁遇到过类似的问题,并解决的?】
zhao4zhong1:
仅供参考:#pragma comment(lib,"user32")
#include &stdio.h&
#include &string.h&
#include &windows.h&
int main() {
SECURITY_ATTRIBUTES sa
STARTUPINFO
PROCESS_INFORMATION pi
hPipeOutputRead
hPipeOutputWrite = NULL;
hPipeInputRead
hPipeInputWrite
bTest = 0;
dwNumberOfBytesRead = 0;
dwNumberOfBytesWrite = 0;
szMsg[100];
szBuffer[256];
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
// Create pipe for standard output redirection.
CreatePipe(&hPipeOutputRead,
// read handle
&hPipeOutputWrite, // write handle
// security attributes
// number of bytes reserved for pipe - 0 default
// Create pipe for standard input redirection.
CreatePipe(&hPipeInputRead,
// read handle
&hPipeInputWrite, // write handle
// security attributes
// number of bytes reserved for pipe - 0 default
// Make child process use hPipeOutputWrite as standard out,
// and make sure it does not show on screen.
si.cb = sizeof(si);
si.dwFlags
= STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.wShowWindow = SW_HIDE;
si.hStdInput
= hPipeInputR
si.hStdOutput
= hPipeOutputW
si.hStdError
= hPipeOutputW
CreateProcess (
NULL, "cmd.exe",
NULL, NULL,
NULL, NULL,
&si, &pi);
// Now that handles have been inherited, close it to be safe.
// You don't want to read or write to them accidentally.
CloseHandle(hPipeOutputWrite);
CloseHandle(hPipeInputRead);
// Now test to capture DOS application output by reading
// hPipeOutputRead.
Could also write to DOS application
// standard input by writing to hPipeInputWrite.
sprintf(szMsg, "ver\n");
WriteFile(
hPipeInputWrite,
// handle of the write end of our pipe
// address of buffer that send data
strlen(szMsg),
// number of bytes to write
&dwNumberOfBytesWrite,// address of number of bytes read
// non-overlapped.
while(TRUE)
bTest=ReadFile(
hPipeOutputRead,
// handle of the read end of our pipe
&szBuffer,
// address of buffer that receives data
// number of bytes to read
&dwNumberOfBytesRead, // address of number of bytes read
// non-overlapped.
if (!bTest){
sprintf(szMsg, "Error #%d reading pipe.",GetLastError());
printf("%s",szMsg);
// do something with data.
szBuffer[dwNumberOfBytesRead] = 0;
// null terminate
printf("%s",szBuffer);
if ('&'==szBuffer[dwNumberOfBytesRead-1])
sprintf(szMsg, "chcp\nexit\n");
WriteFile(
hPipeInputWrite,
// handle of the write end of our pipe
// address of buffer that send data
strlen(szMsg),
// number of bytes to write
&dwNumberOfBytesWrite,// address of number of bytes read
// non-overlapped.
while(TRUE)
bTest=ReadFile(
hPipeOutputRead,
// handle of the read end of our pipe
&szBuffer,
// address of buffer that receives data
// number of bytes to read
&dwNumberOfBytesRead, // address of number of bytes read
// non-overlapped.
if (!bTest){
sprintf(szMsg, "Error #%d reading pipe.",GetLastError());
printf("%s",szMsg);
// do something with data.
szBuffer[dwNumberOfBytesRead] = 0;
// null terminate
printf("%s",szBuffer);
// Wait for CONSPAWN to finish.
WaitForSingleObject (pi.hProcess, INFINITE);
// Close all remaining handles
CloseHandle (pi.hProcess);
CloseHandle (hPipeOutputRead);
CloseHandle (hPipeInputWrite);
//C:\test&test
//Microsoft Windows [版本 5.2.3790]
//(C) 版权所有
Microsoft Corp.
//C:\test&ver
//Microsoft Windows [版本 5.2.3790]
//C:\test&chcp
//活动的代码页: 936
//C:\test&exit
//Error #109 reading pipe.
//C:\test&
CharlesSimonyi:
本帖最后由 CharlesSimonyi 于
19:03:49 编辑
你的python代码是如何反馈进度的?
是用print("10%")之类的方法输出的进度吗?
还是用其他方式。
C代码是如何调用python的,
是通过Python/C API调用
还是把一个py文件当做可执行文件直接用ShellExecute之类的API去执行
lina791211:
int pgPycFtpsFileDownload( const IN
UPGRADE_FTP_INFO * pFtpInfo,
const IN char * pcRemotePath,
const IN char * pcLocalPath,
const IN int ulMaxFileSize)
PyObject * pModule
PyObject * pDict
PyObject * pFunction
PyObject * pArgus
PyObject * pResult
Py_Initialize();
(VOS_VOID)PyRun_SimpleString("import sys");
if(NULL == pModule)
//xxxxxx记录错误
= PyModule_GetDict(pModule);
= PyDict_GetItemString(pDict, "download");
if(NULL == pFunction)
//xxxxxx记录错误
pArgus = Py_BuildValue( "(s, i, s, s, s, s, l)",
pFtpInfo-&ucFtpIp,
pFtpInfo-&ulFtpPort,
pFtpInfo-&ucFtpUsr,
pFtpInfo-&ucFtpPwd,
pcRemotePath,
pcLocalPath,
ulMaxFileSize);
pResult = PyEval_CallObject(pFunction, pArgus);
/*获取download下载结果*/
(void)PyArg_Parse(pResult,"i",ulRet);
Py_Finalize()
//xxxxxx记录日志
return ulR
使用的是Python 的C API方法
lina791211:
def download(ftp_ip, ftp_port, ftp_user, ftp_pwd, remote_file, local_file):
conn_result = _get_remote_file_size(ftp_ip, ftp_port, ftp_user, ftp_pwd, remote_file)
ftps = conn_result[2]
# start to download
local_file_size = 0L
download_result = False
download_size = 0L
ftps.voidcmd("TYPE I")
download_connection = ftps.transfercmd('RETR ' + remote_file, local_file_size)
percent = 0
_progress(CLI_PROCESS_MAX_PRINT_LEN, percent)
# 打开本地文件,准备从远端获取并下载
with open(local_file, "ab") as local_save_file:
while True:
rcv_buffer = download_connection.recv(24)
write_len = local_save_file.write(rcv_buffer)
download_size += len(rcv_buffer)
percent = int(float(download_size) / remote_file_size * 100)
count = (count + 1) % 40 #(延迟打印规则)
if 0 == count:
# 打印进度条,后续删除_progress(CLI_PROCESS_MAX_PRINT_LEN, percent)
if 100 == percent:
# 打印进度条,后续删除 _progress(CLI_PROCESS_MAX_PRINT_LEN, percent)
except Exception, e:
# print "download fail with [%s]" % e
download_result = UPG_FTP_DOWNLOAD_FAIL
# 清理环境
return download_result
这个事是Python的下载组件,有部分是抽出来的方法,没有把代码贴出来。
CharlesSimonyi:
python代码中的download函数又是如何显示进度的?
你的整个下载过程都写到一个函数里了,要调用完毕这个函数才获得结果,而且函数调用完毕的时候整个文件都下载完毕了。
先不说C如何调用的问题,你先解决这样的一个问题:
假如你的这个download函数拿给别人用,别人用python来调用你的download函数,如何实时获取进度并print()输出到屏幕上?
(注意,你写好代码拿给别人用,别人只能调用你写的代码,不能修改你的代码,就像标准库中的那些东西一样,你一般都只是调用,不会去修改它的代码)
所以这其实是个接口设计问题。
一个函数的调用需要很长时间才能完成,如何让调用者获取执行过程的进度,此类问题有多种解决方案:
1.拆分download函数,分步骤实现文件的下载,比如可以拆分成几个函数
打开连接()
获取文件大小()
读一部分(size)
关闭连接()
这样别人调用的时候,可以在一个循环中反复调用
读一部分()并通过参数指定要读多少,这样调用者可以很好的知道进度。
Winhttp/Wininet等HTTP库在下载文件的时候都采用此办法
download应提供一个参数以接收调用者提供的函数指针(或函数对象),download在下载过程中,每下载%5就调用一下这个回调函数通知调用者,这样调用者可以在回调函数中显示进度。
urllib使用的就是这种方式。
3.其它方法,如使用windows消息、事件来通知调用者,具有平台依赖性,用得较少
CharlesSimonyi:
显示进度这种事情不要放在download函数里,你的接口要设计成,当别人调用你的download函数的时候,别人能获取到进度
lina791211:
谢大神,一语惊醒梦中人啊。你的第一个方案非常不错。
第二个方案本来今天想研究一下的,想想太复杂的,就不干了
第三个是不适应的,有平台依赖性。
3Q Very Much!
免责声明:本站部分内容、图片、文字、视频等来自于互联网,仅供大家学习与交流。相关内容如涉嫌侵犯您的知识产权或其他合法权益,请向本站发送有效通知,我们会及时处理。反馈邮箱&&&&。
学生服务号
在线咨询,奖学金返现,名师点评,等你来互动想查reduce, map, filter等python函数的源代码(C或者python源码)在哪里查? - 知乎33被浏览2867分享邀请回答611 条评论分享收藏感谢收起与世界分享知识、经验和见解os、os.path 模块中关于文件、目录常用的函数使用方法,《零基础入门学习Python》,Python交流,鱼C论坛
我的图书馆
os、os.path 模块中关于文件、目录常用的函数使用方法,《零基础入门学习Python》,Python交流,鱼C论坛
&马上注册加入鱼C,享用更多服务吧^_^
才可以下载或查看,没有帐号?
我们第一节课就讲过了,Python是跨平台的语言,也即是说同样的源代码在不同的操作系统不需要修改就可以同样实现。
因此Python的作者就倒腾了OS模块这么一个玩意儿出来,有了OS模块,我们不需要关心什么操作系统下使用什么模块,OS模块会帮你选择正确的模块并调用。
os模块中关于文件/目录常用的函数使用方法
函数名使用方法getcwd()
返回当前工作目录
chdir(path)
改变工作目录
listdir(path='.')
列举指定目录中的文件名('.'表示当前目录,'..'表示上一级目录)
mkdir(path)
创建单层目录,如该目录已存在抛出异常
makedirs(path)
递归创建多层目录,如该目录已存在抛出异常,注意:'E:\\a\\b'和'E:\\a\\c'并不会冲突
remove(path)
rmdir(path)
删除单层目录,如该目录非空则抛出异常
removedirs(path)
递归删除目录,从子目录到父目录逐层尝试删除,遇到目录非空则抛出异常
rename(old, new)
将文件old重命名为new
system(command)
运行系统的shell命令
遍历top路径以下所有的子目录,返回一个三元组:(路径, [包含目录], [包含文件])【具体实现方案请看:第30讲课后作业^_^】
以下是支持路径操作中常用到的一些定义,支持所有平台os.curdir
指代当前目录('.')
指代上一级目录('..')
输出操作系统特定的路径分隔符(Win下为'\\',Linux下为'/')
os.linesep
当前平台使用的行终止符(Win下为'\r\n',Linux下为'\n')
指代当前使用的操作系统(包括:'posix',&&'nt', 'mac', 'os2', 'ce', 'java')
os.path模块中关于路径常用的函数使用方法
函数名使用方法basename(path)
去掉目录路径,单独返回文件名
dirname(path)
去掉文件名,单独返回目录路径
join(path1[, path2[, ...]])
将path1, path2各部分组合成一个路径名
split(path)
分割文件名与路径,返回(f_path, f_name)元组。如果完全使用目录,它也会将最后一个目录作为文件名分离,且不会判断文件或者目录是否存在
splitext(path)
分离文件名与扩展名,返回(f_name, f_extension)元组
getsize(file)
返回指定文件的尺寸,单位是字节
getatime(file)
返回指定文件最近的访问时间(浮点型秒数,可用time模块的gmtime()或localtime()函数换算)
getctime(file)
返回指定文件的创建时间(浮点型秒数,可用time模块的gmtime()或localtime()函数换算)
getmtime(file)
返回指定文件最新的修改时间(浮点型秒数,可用time模块的gmtime()或localtime()函数换算)
以下为函数返回 True 或 Falseexists(path)
判断指定路径(目录或文件)是否存在
isabs(path)
判断指定路径是否为绝对路径
isdir(path)
判断指定路径是否存在且是一个目录
isfile(path)
判断指定路径是否存在且是一个文件
islink(path)
判断指定路径是否存在且是一个符号链接
ismount(path)
判断指定路径是否存在且是一个挂载点
samefile(path1, paht2)
判断path1和path2两个路径是否指向同一个文件
TA的最新馆藏[转]&48611人阅读
Python编程实例(13)
& &&&&Python模块和C/C++的动态库间相互调用在实际的应用中会有所涉及,在此作一总结。
二、Python调用C/C++
1、Python调用C动态链接库
&&&&&&& Python调用C库比较简单,不经过任何封装打包成so,再使用python的ctypes调用即可。
(1)C语言文件:pycall.c
/***gcc -o libpycall.so -shared -fPIC pycall.c*/
#include &stdio.h&
#include &stdlib.h&
int foo(int a, int b)
printf(&you input %d and %d\n&, a, b);
return a+b;
}(2)gcc编译生成动态库libpycall.so:gcc -o libpycall.so -shared -fPIC pycall.c。使用g++编译生成C动态库的代码中的函数或者方法时,需要使用extern &C&来进行编译。
(3)Python调用动态库的文件:pycall.py
import ctypes
ll = ctypes.cdll.LoadLibrary
lib = ll(&./libpycall.so&)
lib.foo(1, 3)
print '***finish***'(4)运行结果:
2、Python调用C++(类)动态链接库
&&&&&& 需要extern &C&来辅助,也就是说还是只能调用C函数,不能直接调用方法,但是能解析C++方法。不是用extern &C&,构建后的动态链接库没有这些函数的符号表。
(1)C++类文件:pycallclass.cpp
#include &iostream&
class TestLib
void display();
void display(int a);
void TestLib::display() {
cout&&&First display&&&
void TestLib::display(int a) {
cout&&&Second display:&&&a&&
extern &C& {
void display() {
obj.display();
void display_int() {
obj.display(2);
}(2)g++编译生成动态库libpycall.so:g++ -o libpycallclass.so -shared -fPIC pycallclass.cpp。
(3)Python调用动态库的文件:pycallclass.py
import ctypes
so = ctypes.cdll.LoadLibrary
lib = so(&./libpycallclass.so&)
print 'display()'
lib.display()
print 'display(100)'
lib.display_int(100)(4)运行结果:
3、Python调用C/C++可执行程序
(1)C/C++程序:main.cpp
#include &iostream&
int test()
int a = 10, b = 5;
return a+b;
int main()
cout&&&---begin---&&&
int num = test();
cout&&&num=&&&num&&
cout&&&---end---&&&
}(2)编译成二进制可执行文件:g++ -o testmain main.cpp。
(3)Python调用程序:main.py
import commands
main = &./testmain&
if os.path.exists(main):
rc, out = commands.getstatusoutput(main)
print 'rc = %d, \nout = %s' % (rc, out)
print '*'*10
f = os.popen(main)
data = f.readlines()
print data
print '*'*10
os.system(main)(4)运行结果:
4、扩展Python(C++为Python编写扩展模块)
&&&&&& 所有能被整合或导入到其它python脚本的代码,都可以被称为扩展。可以用Python来写扩展,也可以用C和C++之类的编译型的语言来写扩展。Python在设计之初就考虑到要让模块的导入机制足够抽象。抽象到让使用模块的代码无法了解到模块的具体实现细节。Python的可扩展性具有的优点:方便为语言增加新功能、具有可定制性、代码可以实现复用等。
&&&&&& 为 Python 创建扩展需要三个主要的步骤:创建应用程序代码、利用样板来包装代码和编译与测试。
(1)创建应用程序代码
#include &stdio.h&
#include &stdlib.h&
#include &string.h&
int fac(int n)
if (n & 2) return(1); /* 0! == 1! == 1 */
return (n)*fac(n-1); /* n! == n*(n-1)! */
char *reverse(char *s)
register char t,
*q = (s + (strlen(s) - 1)); /* bwd */
while (p & q)
/* if p & q */
/* swap & move ptrs */
*p++ = *q;
return(s);
int main()
char s[BUFSIZ];
printf(&4! == %d\n&, fac(4));
printf(&8! == %d\n&, fac(8));
printf(&12! == %d\n&, fac(12));
strcpy(s, &abcdef&);
printf(&reversing 'abcdef', we get '%s'\n&, \
reverse(s));
strcpy(s, &madam&);
printf(&reversing 'madam', we get '%s'\n&, \
reverse(s));
}&&&&&& 上述代码中有两个函数,一个是递归求阶乘的函数fac();另一个reverse()函数实现了一个简单的字符串反转算法,其主要目的是修改传入的字符串,使其内容完全反转,但不需要申请内存后反着复制的方法。
(2)用样板来包装代码
&&&&&&& 接口的代码被称为“样板”代码,它是应用程序代码与Python解释器之间进行交互所必不可少的一部分。样板主要分为4步:a、包含Python的头文件;b、为每个模块的每一个函数增加一个型如PyObject* Module_func()的包装函数;c、为每个模块增加一个型如PyMethodDef ModuleMethods[]的数组;d、增加模块初始化函数void initModule()。
#include &stdio.h&
#include &stdlib.h&
#include &string.h&
int fac(int n)
if (n & 2) return(1);
return (n)*fac(n-1);
char *reverse(char *s)
register char t,
*q = (s + (strlen(s) - 1));
while (s && (p & q))
*p++ = *q;
return(s);
int test()
char s[BUFSIZ];
printf(&4! == %d\n&, fac(4));
printf(&8! == %d\n&, fac(8));
printf(&12! == %d\n&, fac(12));
strcpy(s, &abcdef&);
printf(&reversing 'abcdef', we get '%s'\n&, \
reverse(s));
strcpy(s, &madam&);
printf(&reversing 'madam', we get '%s'\n&, \
reverse(s));
#include &Python.h&
static PyObject *
Extest_fac(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, &i&, &num))
return NULL;
return (PyObject*)Py_BuildValue(&i&, fac(num));
static PyObject *
Extest_doppel(PyObject *self, PyObject *args)
char *orig_
char *dupe_
if (!PyArg_ParseTuple(args, &s&, &orig_str))
return NULL;
retval = (PyObject*)Py_BuildValue(&ss&, orig_str,
dupe_str=reverse(strdup(orig_str)));
free(dupe_str);             #防止内存泄漏
static PyObject *
Extest_test(PyObject *self, PyObject *args)
return (PyObject*)Py_BuildValue(&&);
static PyMethodDef
ExtestMethods[] =
{ &fac&, Extest_fac, METH_VARARGS },
{ &doppel&, Extest_doppel, METH_VARARGS },
{ &test&, Extest_test, METH_VARARGS },
{ NULL, NULL },
void initExtest()
Py_InitModule(&Extest&, ExtestMethods);
}&&&&&& &Python.h头文件在大多数类Unix系统中会在/usr/local/include/python2.x或/usr/include/python2.x目录中,系统一般都会知道文件安装的路径。
&&&&&&& 增加包装函数,所在模块名为Extest,那么创建一个包装函数叫Extest_fac(),在Python脚本中使用是先import Extest,然后调用Extest.fac(),当Extest.fac()被调用时,包装函数Extest_fac()会被调用,包装函数接受一个
Python的整数参数,把它转为C的整数,然后调用C的fac()函数,得到一个整型的返回值,最后把这个返回值转为Python的整型数做为整个函数调用的结果返回回去。其他两个包装函数Extest_doppel()和Extest_test()类似。
&&&&&&&& 从Python到C的转换用PyArg_Parse*系列函数,int PyArg_ParseTuple():把Python传过来的参数转为C;int PyArg_ParseTupleAndKeywords()与PyArg_ParseTuple()作用相同,但是同时解析关键字参数;它们的用法跟C的sscanf函数很像,都接受一个字符串流,并根据一个指定的格式字符串进行解析,把结果放入到相应的指针所指的变量中去,它们的返回值为1表示解析成功,返回值为0表示失败。从C到Python的转换函数是PyObject*
Py_BuildValue():把C的数据转为Python的一个对象或一组对象,然后返回之;Py_BuildValue的用法跟sprintf很像,把所有的参数按格式字符串所指定的格式转换成一个Python的对象。
&&&&&&& C与Python之间数据转换的转换代码:
&&&&&&& 为每个模块增加一个型如PyMethodDef ModuleMethods[]的数组,以便于Python解释器能够导入并调用它们,每一个数组都包含了函数在Python中的名字,相应的包装函数的名字以及一个METH_VARARGS常量,METH_VARARGS表示参数以tuple形式传入。 若需要使用PyArg_ParseTupleAndKeywords()函数来分析命名参数的话,还需要让这个标志常量与METH_KEYWORDS常量进行逻辑与运算常量
。数组最后用两个NULL来表示函数信息列表的结束。
&&&&&&&& 所有工作的最后一部分就是模块的初始化函数,调用Py_InitModule()函数,并把模块名和ModuleMethods[]数组的名字传递进去,以便于解释器能正确的调用模块中的函数。
&&&&&&& 为了让新Python的扩展能被创建,需要把它们与Python库放在一起编译,distutils包被用来编译、安装和分发这些模块、扩展和包。
&&&&&&& 创建一个setup.py 文件,编译最主要的工作由setup()函数来完成:
#!/usr/bin/env python
from distutils.core import setup, Extension
MOD = 'Extest'
setup(name=MOD, ext_modules=[Extension(MOD, sources=['Extest2.c'])])&&&&&&& Extension()第一个参数是(完整的)扩展的名字,如果模块是包的一部分的话,还要加上用'.'分隔的完整的包的名字。上述的扩展是独立的,所以名字只要写&Extest&就行;sources参数是所有源代码的文件列表,只有一个文件Extest2.c。setup需要两个参数:一个名字参数表示要编译哪个内容;另一个列表参数列出要编译的对象,上述要编译的是一个扩展,故把ext_modules参数的值设为扩展模块的列表。
&&&&&&& 运行setup.py build命令就可以开始编译我们的扩展了,提示部分信息:
creating build/lib.linux-x86_64-2.6
gcc -pthread -shared build/temp.linux-x86_64-2.6/Extest2.o -L/usr/lib64 -lpython2.6 -o build/lib.linux-x86_64-2.6/Extest.so(4)导入和测试
&&&&&&&& 你的扩展会被创建在运行setup.py脚本所在目录下的build/lib.*目录中,可以切换到那个目录中来测试模块,或者也可以用命令把它安装到Python中:python setup.py install,会提示相应信息。
&&&&&&&& 测试模块:
(5)引用计数和线程安全
&&&& Python对象引用计数的宏:Py_INCREF(obj)增加对象obj的引用计数,Py_DECREF(obj)减少对象obj的引用计数。Py_INCREF()和Py_DECREF()两个函数也有一个先检查对象是否为空的版本,分别为Py_XINCREF()和Py_XDECREF()。
&&&&& 编译扩展的程序员必须要注意,代码有可能会被运行在一个多线程的Python环境中。这些线程使用了两个C宏Py_BEGIN_ALLOW_THREADS和Py_END_ALLOW_THREADS,通过将代码和线程隔离,保证了运行和非运行时的安全性,由这些宏包裹的代码将会允许其他线程的运行。
三、C/C++调用Python
&&&&&& C++可以调用Python脚本,那么就可以写一些Python的脚本接口供C++调用了,至少可以把Python当成文本形式的动态链接库,
需要的时候还可以改一改,只要不改变接口。缺点是C++的程序一旦编译好了,再改就没那么方便了。
(1)Python脚本:pytest.py
#test function
def add(a,b):
print &in python function add&
print &a = & + str(a)
print &b = & + str(b)
print &ret = & + str(a+b)
def foo(a):
print &in python function foo&
print &a = & + str(a)
print &ret = & + str(a * a)
class guestlist:
def __init__(self):
print &aaaa&
print &bbbbb&
def __getitem__(self, id):
return &ccccc&
def update():
guest = guestlist()
print guest['aa']
#update()(2)C++代码:
/**g++ -o callpy callpy.cpp -I/usr/include/python2.6 -L/usr/lib64/python2.6/config -lpython2.6**/
#include &Python.h&
int main(int argc, char** argv)
// 初始化Python
//在使用Python系统前,必须使用Py_Initialize对其
//进行初始化。它会载入Python的内建模块并添加系统路
//径到模块搜索路径中。这个函数没有返回值,检查系统
//是否初始化成功需要使用Py_IsInitialized。
Py_Initialize();
// 检查初始化是否成功
if ( !Py_IsInitialized() ) {
return -1;
// 添加当前路径
//把输入的字符串作为Python代码直接运行,返回0
//表示成功,-1表示有错。大多时候错误都是因为字符串
//中有语法错误。
PyRun_SimpleString(&import sys&);
PyRun_SimpleString(&print '---import sys---'&);
PyRun_SimpleString(&sys.path.append('./')&);
PyObject *pName,*pModule,*pDict,*pFunc,*pA
// 载入名为pytest的脚本
pName = PyString_FromString(&pytest&);
pModule = PyImport_Import(pName);
if ( !pModule ) {
printf(&can't find pytest.py&);
getchar();
return -1;
pDict = PyModule_GetDict(pModule);
if ( !pDict ) {
return -1;
// 找出函数名为add的函数
printf(&----------------------\n&);
pFunc = PyDict_GetItemString(pDict, &add&);
if ( !pFunc || !PyCallable_Check(pFunc) ) {
printf(&can't find function [add]&);
getchar();
return -1;
// 参数进栈
PyObject *pA
pArgs = PyTuple_New(2);
PyObject* Py_BuildValue(char *format, ...)
把C++的变量转换成一个Python对象。当需要从
C++传递变量到Python时,就会使用这个函数。此函数
有点类似C的printf,但格式不同。常用的格式有
s 表示字符串,
i 表示整型变量,
f 表示浮点数,
O 表示一个Python对象。
PyTuple_SetItem(pArgs, 0, Py_BuildValue(&l&,3));
PyTuple_SetItem(pArgs, 1, Py_BuildValue(&l&,4));
// 调用Python函数
PyObject_CallObject(pFunc, pArgs);
//下面这段是查找函数foo 并执行foo
printf(&----------------------\n&);
pFunc = PyDict_GetItemString(pDict, &foo&);
if ( !pFunc || !PyCallable_Check(pFunc) ) {
printf(&can't find function [foo]&);
getchar();
return -1;
pArgs = PyTuple_New(1);
PyTuple_SetItem(pArgs, 0, Py_BuildValue(&l&,2));
PyObject_CallObject(pFunc, pArgs);
printf(&----------------------\n&);
pFunc = PyDict_GetItemString(pDict, &update&);
if ( !pFunc || !PyCallable_Check(pFunc) ) {
printf(&can't find function [update]&);
getchar();
return -1;
pArgs = PyTuple_New(0);
PyTuple_SetItem(pArgs, 0, Py_BuildValue(&&));
PyObject_CallObject(pFunc, pArgs);
Py_DECREF(pName);
Py_DECREF(pArgs);
Py_DECREF(pModule);
// 关闭Python
Py_Finalize();
} (3)C++编译成二进制可执行文件:g++ -o callpy callpy.cpp -I/usr/include/python2.6 -L/usr/lib64/python2.6/config -lpython2.6,编译选项需要手动指定Python的include路径和链接接路径(Python版本号根据具体情况而定)。
(4)运行结果:
(1)Python和C/C++的相互调用仅是测试代码,具体的项目开发还得参考Python的API文档。
(2)两者交互,C++可为Python编写扩展模块,Python也可为C++提供脚本接口,更加方便于实际应用。
(3)若有不足,请留言,在此先感谢!
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1239686次
积分:12605
积分:12605
排名:第1036名
原创:272篇
转载:101篇
评论:280条
(2)(1)(1)(1)(1)(1)(1)(5)(4)(6)(6)(8)(10)(20)(9)(13)(11)(13)(7)(9)(17)(19)(21)(87)(17)(10)(20)(11)(8)(6)(16)(1)(1)

我要回帖

更多关于 笔记本电脑开机蓝屏怎么解决方法 的文章

 

随机推荐