加解密杂烩程序开发(二)
2015-11-30 21:29
267 查看
这章主要讲述在vc中如何调用Python程序
1、将程序的配置设为release
2、点击“项目”—“属性”—“配置属性”—“VC++目录”,在包含目录和库目录中将当前python程序下的include目录和libs目录的路径加进去。
3、头部添加
#include “python.h”
4、DecryptWork函数内部调用Python,具体步骤为
5、注意点
调用Python传递参数时,VC默认用的宽字节,需要先转为char*传入Python,否则好像会出错。
python返回给VC时,返回的是char*类型,需要先转为宽字节,然后输出。
另外需要注意的一点,调用Unicode加解密时,直接转会出现调用函数出错的情况,用了多种方式也不行,可能是因为char*传进去之后不允许再次进行unicode编码,确切的原因我也不知道。后来用了一种迂回的方式来解决。
新建一个StringToPy函数,用来将char*转为PyObject*类型,然后再传入python程序
传递参数时改为
其他不需要改变,程序执行才不会出错。
1、将程序的配置设为release
2、点击“项目”—“属性”—“配置属性”—“VC++目录”,在包含目录和库目录中将当前python程序下的include目录和libs目录的路径加进去。
3、头部添加
#include “python.h”
4、DecryptWork函数内部调用Python,具体步骤为
Py_Initialize(); //使用python之前,要调用Py_Initialize();这个函数进行初始化 if (!Py_IsInitialized() ) { GetDlgItem(IDC_STATIC)->SetWindowTextW(_T("python初始化失败")); return ; } PyObject * pModule = NULL; //文件名 PyObject * pFunc = NULL; //调用的函数 PyObject *pArgs = NULL; //传递的参数 PyObject *pReturn = NULL; //返回值 pModule =PyImport_ImportModule("decode"); //这里是要调用的Python文件名 if(!pModule) { GetDlgItem(IDC_STATIC)->SetWindowTextW(_T("python引入模块失败")); return ; } pFunc= PyObject_GetAttrString(pModule, "urldecode"); //这里是要调用的函数名 if(!pFunc||!PyCallable_Check(pFunc)) { GetDlgItem(IDC_STATIC)->SetWindowTextW(_T("python引入函数失败")); return ; } //wchar*转为char* int len= WideCharToMultiByte(CP_ACP,0,m_strinput,wcslen(m_strinput),NULL,0,NULL,NULL); char *m_char=new char[len+1]; WideCharToMultiByte(CP_ACP,0,m_strinput,wcslen(m_strinput),m_char,len,NULL,NULL); m_char[len]='\0'; pArgs = PyTuple_New(1); PyTuple_SetItem(pArgs, 0, Py_BuildValue("s", m_char)); pReturn = PyEval_CallObject(pFunc, pArgs); //调用函数,NULL表示参数为空 if(!pReturn) { GetDlgItem(IDC_STATIC)->SetWindowTextW(_T("python执行函数失败")); return ; } //取返回值 char* cstr; PyArg_Parse(pReturn, "s", &cstr); //char*转为wchar* int len1 = MultiByteToWideChar(CP_ACP,0,cstr,strlen(cstr),NULL,0); wchar_t* m_wchar=new wchar_t[len1+1]; MultiByteToWideChar(CP_ACP,0,cstr,strlen(cstr),m_wchar,len1); m_wchar[len1]='\0'; GetDlgItem(IDC_EDIT2)->SetWindowTextW(m_wchar); //后续处理 delete m_char; delete m_wchar; Py_DECREF(pModule); Py_DECREF(pFunc); Py_DECREF(pArgs); Py_DECREF(pReturn); Py_Finalize(); //调用Py_Finalize,这个和Py_Initialize相对应的.
5、注意点
调用Python传递参数时,VC默认用的宽字节,需要先转为char*传入Python,否则好像会出错。
python返回给VC时,返回的是char*类型,需要先转为宽字节,然后输出。
另外需要注意的一点,调用Unicode加解密时,直接转会出现调用函数出错的情况,用了多种方式也不行,可能是因为char*传进去之后不允许再次进行unicode编码,确切的原因我也不知道。后来用了一种迂回的方式来解决。
新建一个StringToPy函数,用来将char*转为PyObject*类型,然后再传入python程序
PyObject* StringToPy(char* p_obj ) { int len1 = MultiByteToWideChar(CP_ACP,0,p_obj,strlen(p_obj),NULL,0); wchar_t* m_wchar=new wchar_t[len1+1]; MultiByteToWideChar(CP_ACP,0,p_obj,strlen(p_obj),m_wchar,len1); m_wchar[len1]='\0'; PyObject* pb=PyUnicode_FromUnicode((const Py_UNICODE*)m_wchar,len1); delete m_wchar; return pb; }
传递参数时改为
PyTuple_SetItem(pArgs, 0, Py_BuildValue("S", StringToPy(m_char)));
其他不需要改变,程序执行才不会出错。
相关文章推荐
- WebKit之Node的继承关系图
- 信息安全系统设计基础第十二周总结
- Oracle Listener 动态注册 与 静态注册
- B. Mike and Fun---cf548B(暴力求解)
- 最新一课 老师指点用Listview适配器
- Hadoop2.6.0学习笔记(四)TextInputFormat及RecordReader解析
- 【Android】RecyclerView的OnItemClickListener点击事件处理
- 谷歌原生下拉刷新SwipeRefreshLayout
- Android代码混淆常见配置
- N皇后问题
- 使用开源C++项目WebSocketpp构建web服务器
- 二叉树镜像(C++版)
- 杭电2039
- 乱七八糟
- 有关于提高C/C++运行效率以及避免出现Bug的几种常见的实用方法
- Java JDBC Thin Driver 连接 Oracle 三种方法说明(转载)
- Struts2——MethodFilterInterceptor--方法拦截器
- 树形dp专题训练
- [leetcode] 191. Number of 1 Bits
- 【VMCloud云平台】私有云门户第一朵Web云(四)