Site-T

SUP-project


  • Home
  • Archive
  • Tags
  •  

© 2019 Time Looper

Theme Typography by Makito

Proudly published with Hexo

sup-002 利用python执行C程序

Posted at 2018-11-14 skill 

利用python执行C程序

首先python自己是无法真正意义上地去执行C语言的代码的,但是我们可以转换思路,利用python调用外部程序来实现。

0.配置环境变量

由于需要调用编译器进行程序的编译运行,故需要在环境变量path中添加编译器地址。

如何找到编译器地址?以codeblocks 为例:在 \CodeBlocks\MinGW\bin 目录下有g++.exe,其他编译器自行手动搜索

配置环境变量:此电脑->属性->(左侧栏的)高级系统设置->高级->环境变量
  双击Path,添加编译器的地址在最后

1.subprocess.call()

虽然有个os的模块同样有os.system()函数来实现执行命令行的操作,但是似乎目前已经被subprocess取代了,同时subprocess 模块的使用灵活度比os大得多,所以在此只介绍使用subprocess模块的情况

如果是Linux系统请下载subprocess32,sudo pip install subprocess32

显然使用这个函数需要包含subprocess的模块,括号中包含的字符串就是你平时在命令提示符窗口输入的指令,除了字符串似乎还支持list不过我不需要。如果是用codeblocks的话可以看到,在编译运行的时候,运行日志的前两行输出了命令行,代码示例:(注意其中的文件名均应该是绝对地址或相对地址)

import subprocess
subprocess.call("mingw32-gcc.exe   -c test.c -o test.o")
subprocess.call("mingw32-g++.exe  -o test.exe test.o")

Linux下的代码:(确保已经安装g++/gcc)

subprocess.call("g++ test.cpp -o test")

当然光是编译运行是不够的,我们要能执行C程序,还要提供输入与输出。如果是直接用subprocess.call("test.exe"),系统默认的输入输出跟python程序的输入输出一样。我们也可以指定从文件输入输出就像是打ACM一样:文件的输入输出记得带上“r” 与“w”参数,否则会出错。

import subprocess
inp=open("in.txt","r")
out=open("res.txt","w")
subprocess.call("test.exe" , stdin=inp,stdout=out)

2.subprocess.Popen()

此处更新于 2019年8月10日,在重新尝试了上述内容后发现了部分需要增加的部分,所以记录在这里。

subprocess.call()函数虽然看起来非常好用但实际上却有着诸多的问题。官方文档告诉我们,在使用call()函数时如果指定了stdout stdin参数,则有可能会导致程序的死锁。同时如果要保证进程的安全,我们需要启用shell=True的参数。如果你是在linux环境下使用subprocess.call(),强烈建议启用shell=True,否则很多需要root权限的操作不能执行,会报错或者死锁。

而出于对call()函数的替代,我们可以使用它的父函数Popen()来完成操作。

Popen()函数同样存在stdin stdout stderr 与 shell等参数。最前面的一个字符串也是当作命令行来操作的。然而Popen()由于开启了新的进程,所以同多线程程序一样,python主程序是不会等待程序的完成的。通常情况下使用wait()函数可以使得主程序等待子进程的完成,但由于wait()是接收到子进程的return值后终结的,故当你指定了stdout 或stderr时可能会产生死锁现象。为了避免死锁建议使用communicate()函数。并且communicate()函数可以给子进程提供输出。使用示例:

child=subprocess.Popen("test.exe",stdout=out)
child.communicate(inp.read())

如果要考虑对子程序的更高级的使用,可以考虑使用terminate() 与kill()函数等,进行配合使用。具体参见官方文档

Share 

 Previous post: sup-extra HYSBZ-2809 dispatching 左偏树 Next post: introduction 

© 2019 Time Looper

Theme Typography by Makito

Proudly published with Hexo