您的位置:首页 > 编程语言 > Python开发

VC与Python交互

2011-08-03 23:38 253 查看
一。静态编译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 测试代码

view
plain

#include <stdio.h>

#include "python.h"



int main()

{

Py_Initialize();

PyRun_SimpleString("print 'i am a static python exe!!!'");

Py_Finalize();

return 0;

}

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

1 打开Python25的lib文件夹,将所有文件拷出来,进入此目录执行python -OO compileall.py -f,将所有文件.py -> .pyo

2 删除除.pyo之外的所有文件,然后打包为python25.zip

3 在Python的初始化部分添加如下代码,将此zip添加到sys.path



view
plain

char szCmd[MAX_PATH];

char* szPath = "E://root//MyGame//lib";

sprintf(szCmd, "import sys/n"

"sys.path=['.', r'%s//python25.zip', r'%s']/n"

"import main/n",

szPath, szPath, szPath);

Py_OptimizeFlag = 2;

Py_NoSiteFlag = 1;

Py_Initialize(); // 初始化

PyRun_SimpleString(szCmd);

三。自定义Python模块/函数

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

view
plain

extern "C" static PyObject* SendStringInt(PyObject *pSelf, PyObject *pParams)

{

char* strMessage = 0;

int nCount;

if(!PyArg_ParseTuple(pParams, "si", &strMessage, &nCount))

{

QDLogs.SendMsg(LOG_OUTPUT_ERROR_TEAM, "uable to parse parameter tuple");

return 0;

}

QDLogs.SendMsg(LOG_OUTPUT_ERROR_TEAM, strMessage);

return (PyObject*)Py_None;

}

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

view
plain

extern "C" PyMethodDef QDMethods [] =

{

{"sendStringInt", SendStringInt, METH_VARARGS, "SendStringInt" },

{NULL, NULL, NULL, NULL}

};

3 注册模块



view
plain

void QdaoPythonManager::AddPythonModule(char* szModuleName, PyMethodDef* pDef)

{

class PyThreadStateLock PyThreadLock;

if(!PyImport_AddModule(szModuleName))

{

QDLogs.SendMsg(LOG_OUTPUT_ERROR_TEAM, "%s module could not be created", szModuleName);

return;

}

// 将函数表加入这个模块

if(!Py_InitModule(szModuleName, pDef))

{

QDLogs.SendMsg(LOG_OUTPUT_ERROR_TEAM, "%s API module could not be initialized", szModuleName);

return;

}

return;

}

QdaoPythonManager::Instance().AddPythonModule("QD", QDMethods);

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

view
plain

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

四。C执行Python文件

view
plain

extern "C" bool RunFyFuntion(char *strFilename, char *strModuleName, char *strFunctionName)

{

PyObject *pParams = NULL;

PyObject *pModuleOld = NULL;

PyObject *pModule =NULL;

PyObject *pName = NULL;

PyObject *pResult = NULL;

PyObject *pDict = NULL;

PyObject *pFunc = NULL;

bool bResult = false;



class PyThreadStateLock PyThreadLock;



pName = PyString_FromString(strFilename);

pModuleOld = PyImport_Import(pName);

if(!pModuleOld)

{

QDLogs.SendMsg(LOG_OUTPUT_ERROR_TEAM, "%s file read error", strFilename);

goto last;

}



pModule = PyImport_ReloadModule(pModuleOld);

if(!pModule)

{

QDLogs.SendMsg(LOG_OUTPUT_ERROR_TEAM, "%s file read error", strFilename);

goto last;

}



pDict = PyModule_GetDict(pModule);



// 获得函数名

pFunc = PyDict_GetItemString(pDict, strFunctionName);

if (!pFunc || !PyCallable_Check(pFunc))

{

QDLogs.SendMsg(LOG_OUTPUT_ERROR_TEAM, "%s function read error", strFunctionName);

goto last;

}



// 设置参数

pParams = PyTuple_New(2);

PyTuple_SetItem(pParams, 0, Py_BuildValue("s", "abc"));

PyTuple_SetItem(pParams, 1, Py_BuildValue("i", 1));



// 执行函数

pResult = PyObject_CallObject(pFunc, pParams);

if(pResult == Py_True)

{

bResult = true;

}

else

{

QDLogs.SendMsg(LOG_OUTPUT_ERROR_TEAM, "%s function run error", strFunctionName);

goto last;

}



last:

Py_XDECREF(pFunc);

Py_XDECREF(pDict);

Py_XDECREF(pParams);

Py_XDECREF(pModuleOld);

Py_XDECREF(pModule);

Py_XDECREF(pName);

Py_XDECREF(pResult);

return bResult;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: