VC与Python交互

一。静态编译Python的方法

1 准备工作
   a 到http://www.python.org/ftp/python/2.5.4/下个包Python-2.5.4.tar.bz2
   b 进入Python-2.5.4/PCbuild8 ,打开解决方案pcbuild.sln
   c 修改pythoncore的编译配置:
     Config Type -> .lib
     RunTime Library -> MT / MTD
   d 按顺序编译
      make_buildinfo
      make_versioninfo
      pythoncore
      注:如果无法打开工程,可能是工程文件首行<?xml version="1.0" encoding="Windows-1252"?>的问题
   e 确认以下文件是否生成,关闭pcbuild.sln
      getbuildinfo.c
      pythonnt_rc_d.h
      pythonnt_rc.h

 

2 嵌入工程
   a 打开需要嵌入Python的工程,将pythoncore导入
   b 将pythoncore中Build Events的事件 cd $(SolutionDir) make_buildinfo/make_buildinfo.exe取消
   c 修改lib的输出位置,与源工程匹配,并将输出文件改为 python25_d.lib / python25.lib
   d 配置include目录,
      Python-2.5.4/PC
      Python-2.5.4/Include
   e 配置RunTime Library -> MT / MTD
    f 配置c/c++项中: preproccessor 的 preproccessor Definitions 添加一个宏: Py_NO_ENABLE_SHARED
   g 配置Linker中Genral的:Additional Library Directories 为 python25.lib所在目录
      配置Linker中Input的 Additional Dependencies 为 python25_d.lib / python25.lib
   h rebuild

 

3 测试代码

  1. #include <stdio.h>  
  2. #include "python.h"  
  3.   
  4. int main()  
  5. {  
  6.     Py_Initialize();  
  7.     PyRun_SimpleString("print 'i am a static python exe!!!'");  
  8.     Py_Finalize();  
  9.     return 0;  
  10. }  

二。Pythoncore嵌入解决import site出错的问题

1 打开Python25的lib文件夹,将所有文件拷出来,进入此目录执行python -OO compileall.py -f,将所有文件.py -> .pyo
2 删除除.pyo之外的所有文件,然后打包为python25.zip
3 在Python的初始化部分添加如下代码,将此zip添加到sys.path

 

  1. char szCmd[MAX_PATH];  
  2. char* szPath = "E://root//MyGame//lib";  
  3. sprintf(szCmd, "import sys/n"   
  4.                 "sys.path=['.', r'%s//python25.zip', r'%s']/n"            
  5.                 "import main/n",              
  6.         szPath, szPath, szPath);  
  7. Py_OptimizeFlag = 2;  
  8. Py_NoSiteFlag = 1;  
  9. Py_Initialize();                                            // 初始化  
  10. PyRun_SimpleString(szCmd); 

三。 自定义Python模块/函数

1 首先定义一个函数,其中PyArg_ParseTuple来获得参数,si表示第一个是string,第二个是int

  1. extern "C" static PyObject* SendStringInt(PyObject *pSelf, PyObject *pParams)  
  2. {  
  3.     char* strMessage = 0;  
  4.     int nCount;  
  5.     if(!PyArg_ParseTuple(pParams, "si", &strMessage, &nCount))  
  6.     {  
  7.         QDLogs.SendMsg(LOG_OUTPUT_ERROR_TEAM, "uable to parse parameter tuple");  
  8.         return 0;  
  9.     }  
  10.     QDLogs.SendMsg(LOG_OUTPUT_ERROR_TEAM, strMessage);  
  11.     return (PyObject*)Py_None;  
  12. }  

2 做一个方法表,为自定义模块做准备,数组最后一个值要全为NULL

  1. extern "C" PyMethodDef QDMethods [] =  
  2. {  
  3.     {"sendStringInt", SendStringInt, METH_VARARGS, "SendStringInt" },  
  4.     {NULL, NULL, NULL, NULL}              
  5. };  

3 注册模块

 

  1. void QdaoPythonManager::AddPythonModule(char* szModuleName, PyMethodDef* pDef)  
  2. {  
  3.     class PyThreadStateLock PyThreadLock;   
  4.     if(!PyImport_AddModule(szModuleName))  
  5.     {  
  6.         QDLogs.SendMsg(LOG_OUTPUT_ERROR_TEAM, "%s module could not be created", szModuleName);  
  7.         return;  
  8.     }  
  9.     // 将函数表加入这个模块  
  10.     if(!Py_InitModule(szModuleName, pDef))  
  11.     {  
  12.         QDLogs.SendMsg(LOG_OUTPUT_ERROR_TEAM, "%s API module could not be initialized", szModuleName);  
  13.         return;  
  14.     }  
  15.     return;  
  16. }  
  17. QdaoPythonManager::Instance().AddPythonModule("QD", QDMethods);  

4 这样就可以在Python中调用了,在C中快速执行Python可以:

  1. PyRun_SimpleString("import QD;QD.sendStringInt('哈哈', 1)"); 

四。 C执行Python文件

  1. extern "C" bool RunFyFuntion(char *strFilename, char *strModuleName, char *strFunctionName)  
  2. {  
  3.     PyObject *pParams = NULL;  
  4.     PyObject *pModuleOld = NULL;  
  5.     PyObject *pModule =NULL;  
  6.     PyObject *pName = NULL;  
  7.     PyObject *pResult = NULL;  
  8.     PyObject *pDict = NULL;   
  9.     PyObject *pFunc = NULL;  
  10.     bool bResult = false;  
  11.       
  12.     class PyThreadStateLock PyThreadLock;  
  13.   
  14.     pName = PyString_FromString(strFilename);  
  15.     pModuleOld = PyImport_Import(pName);      
  16.     if(!pModuleOld)  
  17.     {  
  18.         QDLogs.SendMsg(LOG_OUTPUT_ERROR_TEAM, "%s file read error", strFilename);  
  19.         goto last;  
  20.     }  
  21.   
  22.     pModule = PyImport_ReloadModule(pModuleOld);  
  23.     if(!pModule)  
  24.     {  
  25.         QDLogs.SendMsg(LOG_OUTPUT_ERROR_TEAM, "%s file read error", strFilename);  
  26.         goto last;  
  27.     }  
  28.   
  29.     pDict = PyModule_GetDict(pModule);  
  30.   
  31.     // 获得函数名  
  32.     pFunc = PyDict_GetItemString(pDict, strFunctionName);  
  33.     if (!pFunc || !PyCallable_Check(pFunc))  
  34.     {  
  35.         QDLogs.SendMsg(LOG_OUTPUT_ERROR_TEAM, "%s function read error", strFunctionName);  
  36.         goto last;  
  37.     }  
  38.   
  39.     // 设置参数  
  40.     pParams = PyTuple_New(2);                                     
  41.     PyTuple_SetItem(pParams, 0, Py_BuildValue("s""abc"));  
  42.     PyTuple_SetItem(pParams, 1, Py_BuildValue("i", 1));  
  43.   
  44.     // 执行函数  
  45.     pResult = PyObject_CallObject(pFunc, pParams);    
  46.     if(pResult == Py_True)  
  47.     {  
  48.         bResult = true;  
  49.     }  
  50.     else  
  51.     {  
  52.         QDLogs.SendMsg(LOG_OUTPUT_ERROR_TEAM, "%s function run error", strFunctionName);  
  53.         goto last;  
  54.     }  
  55.   
  56. last:  
  57.     Py_XDECREF(pFunc);  
  58.     Py_XDECREF(pDict);  
  59.     Py_XDECREF(pParams);  
  60.     Py_XDECREF(pModuleOld);  
  61.     Py_XDECREF(pModule);  
  62.     Py_XDECREF(pName);  
  63.     Py_XDECREF(pResult);  
  64.     return bResult;  
  65. }  

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值