python资料

  • F2_622769
    了解作者
  • 7.5MB
    文件大小
  • zip
    文件格式
  • 0
    收藏次数
  • VIP专享
    资源类型
  • 0
    下载次数
  • 2022-05-17 06:46
    上传日期
Python调用C++或者C++调用python的资料
python.zip
  • python
  • xerces安装说明.txt
    489B
  • xerces-c-src_2_8_0.tar.gz
    7.5MB
  • 如何让python调用C和C++代码.docx
    14.7KB
  • Python调用C++.txt
    12.6KB
内容介绍
这是件非常有趣并耐人寻味的过程,我们的MT(Mobile Test)课题采用了脚本自动化测试技术,当初选择了Python作为脚本语言,而Python并不能为我们完成所有的工作,我们要用C++扩展Python,用的是Boost库。之后,我们又要在我们的项目的C++代码中调用Python脚本。下面,我们首先看看Python调用C/C++的过程吧。 Python开发效率高,运行效率低。而c/c++恰恰相反。因此在python脚本中调用c/c++的库,对python进行扩展,是很有必要的。使用python api,http://www.python.org/doc/,需要安装python-dev。 不使用Boost的情况: test.c文件如下 1.#include <Python.h>//包含python的头文件 2.// 1 c/cpp中的函数 3.int my_c_function(const char *arg) 4.{ 5. int n = system(arg); 6. return n; 7.} 8.// 2 python 包装 9.static PyObject * wrap_my_c_fun(PyObject *self, PyObject *args) 10.{ 11. const char * command; 12. int n; 13. if (!PyArg_ParseTuple(args, "s", &command))//这句是把python的变量args转换成c的变量command 14. return NULL; 15. n = my_c_function(command);//调用c的函数 16. return Py_BuildValue("i", n);//把c的返回值n转换成python的对象 17.} 18.// 3 方法列表 19.static PyMethodDef MyCppMethods[] = { 20.//MyCppFun1是python中注册的函数名,wrap_my_c_fun是函数指针 21. {"MyCppFun1", wrap_my_c_fun, METH_VARARGS, "Execute a shell command."}, 22. {NULL, NULL, 0, NULL} 23.}; 24.// 4 模块初始化方法 25.PyMODINIT_FUNC initMyCppModule(void) 26.{ 27.//初始模块,把MyCppMethods初始到MyCppModule中 28. PyObject *m = Py_InitModule("MyCppModule", MyCppMethods); 29. if (m == NULL) return; 30.} test.py文件如下 1.import MyCppModule//导入python的模块(也就是c的模块,注意so文件名是MyCppModule 2.r = MyCppModule.MyCppFun1("ls -l")//调用 3.print r 4.print "OK" 使用Boost的情况: hello.cpp char const* greet() { return "hello, world"; } #include <boost/python.hpp> BOOST_PYTHON_MODULE(hello_ext) { using namespace boost::python; def("greet", greet); } 采用Boost build编译后 >>> import hello_ext >>> print hello.greet() hello, world 整个过程还是比较简单,但是环境配置还是比较麻烦的,请参考我以前的文章——Boost.Python在VS2005下的环境搭建有感而发 上次我写了利用Python提供的API封装c函数,并调用。但是由于利用API的方式过于原始,对于类或者结构极度麻烦。因此,我选择了Boost的Python的来封装类,类似的工具还有SWIG等,选择Boost的原因是它不需要引入其他的接口描述语言,封装也是c++代码;另外,它支持的c++特性比较全。 Boost Python的文档,我推荐:http://www.maycode.com/boostdoc/boost-doc/libs/python/doc/。基本上,你遇到的问题,都可以找到答案。 下面贴一个例子,这个例子覆盖的面很全,需要好好理解。这个例子,是研究怎么封装C++。下一节,我会写一些高级的用法。 1.#include 2.#include 3.#include 4.#include 5.#include 6.using namespace std; 7.using namespace boost::python; 8.namespace HelloPython{ 9. // 简单函数 10. char const* sayHello(){ 11. return "Hello from boost::python"; 12. } 13. // 简单类 14. class HelloClass{ 15. public: 16. HelloClass(const string& name):name(name){ 17. } 18. public: 19. string sayHello(){ 20. return "Hello from HelloClass by : " + name; 21. } 22. private: 23. string name; 24. }; 25. // 接受该类的简单函数 26. string sayHelloClass(HelloClass& hello){ 27. return hello.sayHello() + " in function sayHelloClass"; 28. } 29. //STL容器 30. typedef vector<int> ivector; 31. //有默认参数值的函数 32. void showPerson(string name,int age=30,string nationality="China"){ 33. cout << name << " " << age << " " << nationality << endl; 34. } 35. // 封装带有默认参数值的函数 36. BOOST_PYTHON_FUNCTION_OVERLOADS(showPerson_overloads,showPerson,1,3) //1:最少参数个数,3最大参数个数 37. // 封装模块 38. BOOST_PYTHON_MODULE(HelloPython){ 39. // 封装简单函数 40. def("sayHello",sayHello); 41. // 封装简单类,并定义__init__函数 42. class_("HelloClass",init()) 43. .def("sayHello",&HelloClass::sayHello)//Add a regular member function 44. ; 45. def("sayHelloClass",sayHelloClass); // sayHelloClass can be made a member of module!!! 46. // STL的简单封装方法 47. class_("ivector") 48. .def(vector_indexing_suite()); 49. class_ >("ivector_vector") 50. .def(vector_indexing_suite >()); 51. // 带有默认参数值的封装方法 52. def("showPerson",showPerson,showPerson_overloads()); 53. } 前两篇都是介绍Python调用C++的,换句话说,就是需要把C++封装成Python可以“理解”的类型。这篇,我打算说一下,C++怎么去调用Python脚本。其实这两者之间是相通的,就是需要可以互操作。按照惯例,先贴代码。 second.cpp 1.#include <Python.h> 2.#include <iostream> 3.#include <string> 4.void printDict(PyObject* obj) 5.{ 6. if( !PyDict_Check(obj)) 7. return; 8. PyObject *k,*keys; 9. keys = PyDict_Keys(obj); 10. for(int i = 0; i < PyList_GET_SIZE(keys); i++) 11. { 12. k = PyList_GET_ITEM(keys, i); 13. char* c_name = PyString_AsString(k); 14. printf("%s/n",c_name); 15. } 16.} 17.int main() 18.{ 19. Py_Initialize(); 20. if(!Py_IsInitialized()) 21. return -1; 22. PyRun_SimpleString("import sys"); 23. PyRun_SimpleString("sys.path.append('./')"); 24. //导入模块 25. PyObject* pModule=PyImport_ImportModule("second"); 26. if(!pModule) 27. { 28. printf("Cant open python file!/n"); 29. return -1; 30. } 31. //模块的字典列表 32. PyObject* pDict = PyModule_GetDict(pModule); 33. if(!pDict) 34. { 35. printf("Cant find dictionary./n"); 36. return -1; 37. } 38. //打印出来看一下 39. printDict(pDict); 40. //获取Second类 41. PyObject* pClassSecond = PyDict_GetItemString(pDict,"Second"); 42. if( !pClassSecond ) 43. { 44. printf("Cant find second class./n"); 45. return -1; 46. } 47. //构造Second的实例 48. PyObject* pInstanceSecond = PyInstance_New(pClassSecond,NULL,NULL); 49. if( !pInstanceSecond) 50. { 51. printf("Cant create second instance./n"); 52. return -1; 53. } 54. //获取Person类 55. PyObject* pClassPerson = PyDict_GetItemString(pDict,"Person"); 56. if( !pClassPerson ) 57. { 58. printf("Cant find person class./n"); 59. return -1; 60. } 61. //构造Person的实例 62. PyObject* pInstancePerson = PyInstance_New(pClassPerson,NULL,NULL); 63. if( !pInstancePerson ) 64. { 65. printf("Cant find person instance./n"); 66. return -1; 67. } 68. PyObject_CallMethod(pInstanceSecond,"invoke","O",pInstancePerson); 69. Py_DECREF(pModule); //都需要释放,例子就不写了 70. Py_Finalize(); 71. getchar(); 72. return 0; 73.} second.py 1.#!/usr/bin/python 2.# Filename: second.py 3.class Person: 4. def sayHi(self): 5. print 'hi' 6.class Second: 7. def sayHello(self): 8. print 'hello' 9. def invoke(self,obj): 10. obj.sayHi() 我简单解释一下 ?这个例子演示了,创建python中Person类的实例,并作为参数调用Second的方法。 ?Py_Initialize()和Py_Finalize()是初始和销毁Python解释器 ?PyRun_SimpleString("import sys")导入sys,接着设置py文件的路径PyRun_SimpleString("sys.path.append('./')") ?导入模块PyImport_ImportModule("second"),就是second.py模块。 ?获取模块字典列表,PyModule_GetDict(pModule),可以打印出来看一下如void printDict(PyObject* obj)函数 ?从字典中获取类的类型PyDict_GetItemString(pDict,"Second"),如函数也是这样获取的 ?创造类的实例PyInstance_New(pClassSecond,NULL,NULL) ?调用实例的方法PyObject_CallMethod(pInstanceSecond,"invoke","O",pInstancePerson) 整个流程就是这样的,并不复杂,如果要进一步研究可以参考:http://www.python.org/doc/ ?Extending and Embedding ?Python/C API 比较特殊的是调用Python函数时,参数的传递,就是c++的类型,怎么转换成Python的类型;另外一个问题是,Python函数的返回值,怎么转换成C++中的类型
评论
    相关推荐
    • c++嵌入python
      c++嵌入python,举例,基于vs2003
    • C++调用python demo
      写了一个C++调用python的小代码,调用python的流程有点繁琐,但是借机可以理解python的机理和调用过程,欢迎下载!
    • python重写C++
      python重写的C++脚本,都是一些简单的例子
    • C++调用Python脚本
      完整的C++调用Python脚本源码,包含参数传递和函数返回值处理等,且解决传递中文参数出现乱码等问题
    • C++扩展Python源码
      一份用C++扩展Python的源代码。例子虽然简单,但却有启发意义。 特别是,这是用C++Python3.1环境写的一个扩展小例子。
    • C++调用python函数
      C++调用python发邮件的函数,一个简单实例,注释很详细,其中要注意字符编码是utf-8,程序中不能有中文字符
    • swig 打包C++ python应用
      swig 打包C/C++程序;供python调用。 本软件操作平台windows 10 Vs2017;python3.8; 主要讲述swig vs配置,测试用例。 主要包含常量,变量,指针,结构体定义及运用。
    • C++ Python 标准库.zip
      C++ 标准库 python标准库 投入一点 收入多多 。。。。。
    • C++调用python实例
      c++调用Python实例,测试通过可以运行,实现了多个整数参数之间的传递,实现多个list传递。我博客有对应文章讲解
    • C++ Python language bindings-开源
      该项目将帮助您将C ++库公开给Python。 pygccxml包是用于读取C ++声明的面向对象的框架。 pyplusplus软件包是一个面向对象的框架,用于为boost.python库创建代码生成器。