python 中调用c++定义的函数
来源:互联网 发布:公司网络被限制怎么办 编辑:程序博客网 时间:2024/05/21 17:47
最近项目需要实现这样的需求,后台更改了数据库后,需要在不重启gameserver的情况下,重新加载数据。由于前不久写过监控gameserver的监控程序,发短信那块用的python写的,就想直接在上面扩展下,添加一个非常简单的http服务器,后台改变数据后,发送一个http请求给这个监控程序,监控程序再去请求gameserver,重新加载数据。
上网搜了一下,发现在python 中调用c++中函数,网上大部分方法都是将c++编成.dll(windows下)或者.so(linux下),这样和我们现在的需求不一致,c++写的程序是要一直运行,当python脚本中的httpserver接收到特定的请求再调用c++的函数。
现在我们就不将c++定义的函数编成.dll的方法,python弄个非常简单的http server,接收到get请求后调用c++的测试函数(无参打印函数,有参的加法函数)。
其实只需要调用python提供的api直接在c++中创建python模块并将需要的函数初始化进去,在python中import此模块,调用相应的函数即可。
最主要的就是定义PyMethodDef类型的数组,例如这里使用的:
static PyMethodDef Methods[]={{"no_args_function_print", noArgsFunctionPrint, METH_NOARGS, NULL},{"args_function_add", argsFunctionAdd, METH_VARARGS, NULL},{NULL, NULL, 0, NULL} };数组中的第一个数组变量中第一个是导出到python中使用的函数名,第二个是c++中定义的函数指针,第三个是参数类型,种类很多,我们这里只使用两种:无参用METH_NOARGS,有参用METH_VARARGS。第四个参数是此函数的doc说明。
c++中要实现的函数这样定义:static PyObject* PyMethodDef数组中定义的函数指针(PyObject *pSelf, PyObject *pParams); 里面实现逻辑,第一个参数是此函数的类类型。这里没用,第二个参数是python调用的时间传入的。
现在我们来实现上面的简单需求,先看看python脚本:python_call_c++.py
# -*- coding: UTF-8 -*-import BaseHTTPServer import urlparse"""引入c++中定义的python模块"""import ModuleOfDefineclass WebRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): def do_GET(self): """ """ parsed_path = urlparse.urlparse(self.path) message_parts = [ 'CLIENT VALUES:', 'client_address=%s (%s)' % (self.client_address, self.address_string()), 'command=%s' % self.command, 'path=%s' % self.path, 'real path=%s' % parsed_path.path, 'query=%s' % parsed_path.query, 'request_version=%s' % self.request_version, '', 'SERVER VALUES:', 'server_version=%s' % self.server_version, 'sys_version=%s' % self.sys_version, 'protocol_version=%s' % self.protocol_version, '', 'HEADERS RECEIVED:', ] """调用c++中定义的no_args_function_print函数""" ModuleOfDefine.no_args_function_print() """调用c++中定义的args_function_add函数""" return_value = ModuleOfDefine.args_function_add(1, 3) print "python call c++ function add return value: ", return_value for name, value in sorted(self.headers.items()): message_parts.append('%s=%s' % (name, value.rstrip())) message_parts.append('') message = '\r\n'.join(message_parts) self.send_response(200) self.end_headers() self.wfile.write(message)server = BaseHTTPServer.HTTPServer(('0.0.0.0',8080), WebRequestHandler) server.serve_forever()
这个是网上down的一个非常简单的http服务器,再看看c++代码:
#include "python.h"#include <iostream>// 测试的无参函数static PyObject* noArgsFunctionPrint(PyObject *pSelf, PyObject *pParams){std::cout << "python already call c++ funcions, this this noArgsFunctionPrint!" << std::endl;Py_INCREF(Py_None);return Py_None;}// 测试的有参函数static PyObject* argsFunctionAdd(PyObject *pSelf, PyObject *pParams){std::cout << "python already call c++ funcions, this is argsFunctionAdd" << std::endl;long x = 0;long y = 0;// 获取python调用此函数时传进的参数if (!PyArg_ParseTuple(pParams, "ii", &x, &y)){return NULL;}long result = x + y;return PyInt_FromLong(result);}// 将c++中需要导出的函数的名字、函数地址等信息保存到PyMethodDef类型的数组中// 导出到python的函数名、函数指针、函数形式(我们这使用这两种:METH_NOARGS(没参数),METH_VARARGS(有参数))、函数的doc// 最后一行的NULL时结束标记static PyMethodDef Methods[]={{"no_args_function_print", noArgsFunctionPrint, METH_NOARGS, NULL},{"args_function_add", argsFunctionAdd, METH_VARARGS, NULL},{NULL, NULL, 0, NULL} };// 调用python_call_c++.py脚本void initPython(){//初始化系统中得python解释器Py_Initialize();//python的解释器是否已经初始化,返回true(非0)表明已经初始化,返回false(0)表明没有初始化 if (!Py_IsInitialized()){std::cout << "Py_Initialize() failed" << std::endl;system("pause");return;}// 向python中添加参数名的模块if (!PyImport_AddModule("ModuleOfDefine")){std::cout << "c++ add module could not be created." << std::endl;}// 初始化添加的模块PyObject *module = Py_InitModule("ModuleOfDefine", Methods);if (!module){std::cout << "c++ add module could not be initialized." << std::endl;return;}PyRun_SimpleString("import sys");PyRun_SimpleString("sys.path.append('./')");PyObject *pName = NULL;PyObject *pModule = NULL;//载入python_call_c++.py脚本pName = PyString_FromString("python_call_c++");pModule = PyImport_Import(pName);if (!pModule){std::cout << "can not find python_call_c++.py" << std::endl;system("pause");return;}//释放资源 if (pName != NULL){Py_DECREF(pName);}if (pModule != NULL){Py_DECREF(pModule);}//关闭pythonPy_Finalize();}int main(){initPython();system("pause");return 0;}
c++ 代码中有很详细的注释了,前面也说过c++中如何调用python,可以参考下http://blog.csdn.net/u014489596/article/details/42146233
可以测试下,开启c++程序后,打开浏览器,输入http://localhost:8080/就行了。
- python 中调用c++定义的函数
- [C#]调用字符串中定义的函数
- 在.c文件中调用c++定义的函数
- C++调用C文件中定义的函数接口
- python调用c中函数
- Python函数的定义和调用
- Python函数的定义和调用
- Python 07 函数的定义与调用
- C调用Python的函数
- Python调用 c 的函数
- C调用Python的函数
- Python中类的定义与调用
- CUDA常见问题之无法在c文件中调用cu文件中定义的函数
- VS开发】C中调用C++文件中定义的function函数
- CUDA 问题解决 ——在 c 文件中调用 cu 文件中定义的函数失败
- python 调用dll中参数为BYTE的函数(注意接口定义的格式)
- Python定义的函数(或调用)中参数*args 和**kwargs的用法
- 【python】函数定义 参数 调用
- 深入理解Java内存模型(五)——锁
- grunt入门讲解3:实例讲解使用 Gruntfile 配置任务
- 姚博文 springsecurity restful 自定义 csrf
- insmod: error inserting 'hello.ko': -1 Invalid module format
- 面试问题如何回答?
- python 中调用c++定义的函数
- IP数据包在网络中的转发分析
- usb设备请求命令详解
- Linux系统上的Watchdog实现
- 20150123 N2
- nginx+tomcat实现动静分离
- Metro UI CSS 学习笔记之组件(菜单与导航)
- Python编码格式说明及转码函数encode和decode的使用
- jQuery Tween缓动算法