一、问题:
现在有一个C++类库Mythma.dll,需要Python用户也可以调用这些服务,所以需要用封装其为Python扩展模块Mythma.pyd。
现在有可执行程序PythonConsole.exe,依赖Mythma.dll模块,希望PythonConsole.exe可以调用Python脚本,所以PythonConsole.exe中需要嵌入Python解析器。
此时,PythonConsole.exe既可以直接访问Mythma.dll,又可以通过Python脚本访问Mythma.dll。关系图如下:
二、实现
1、假设Mythma.dll中的类为CHelloWorld
class MythmaAPI CHelloWorld
{
public:
CHelloWorld(void);
~CHelloWorld(void);
void SetId(int nId) { m_Id = nId;}
int GetId() const { return m_Id; }
private:
int m_Id;
};
2、用Boost.Python将C++模块封装,使得Python脚本可以调用C++的功能
如:
#include "HelloWorld.h"
#include <boost/python.hpp>
using namespace boost::python;
BOOST_PYTHON_MODULE(MythmaPy)
{
class_<CHelloWorld>("CHelloWorld")
.def("SetId", &CHelloWorld::SetId)
.def("GetId", &CHelloWorld::GetId)
;
}
此时,可以用Python脚本访问Mythma.dll中的类,axxscript.py文件中的内容为:
#import MythmaPy
from MythmaPy import *
world = CHelloWorld()
world.SetId(100)
print world.GetId()
3、在C++程序里内嵌Python解析器,使得C++可以调用Python脚本
建立一个控制台程序PythonConsole.exe,用来嵌入Python解析器
int main(int argc, char **argv)
{
// Initialize the interpreter
Py_Initialize();
if (python::handle_exception(exec_mythma))
{
if (PyErr_Occurred())
{
BOOST_ERROR("Python Error detected");
PyErr_Print();
}
else
{
BOOST_ERROR("A C++ exception was thrown for which "
"there was no exception translator registered.");
}
}
char ch;
std::cin >> ch;
// Boost.Python doesn't support Py_Finalize yet, so don't call it!
return boost::report_errors();
}
执行调用Python脚本的过程如下:
void exec_mythma()
{
std::cout << "exec extension module Mythma" << std::endl;
python::dict global;
python::object result = python::exec_file(
".\\axxscript.py", global, global);
python::object world = global["world"];
CHelloWorld& py = python::extract<CHelloWorld&>(world) BOOST_EXTRACT_WORKAROUND;
std::cout << py.GetId() << std::endl;
std::cout << "success!" << std::endl;
}
三、症状
通过执行PythonConsole.exe无法正常调用脚本,错误信息如下:
假如直接运行脚本,结果正确。不知各位朋友发现问题的原因没有?有什么解决方法?
四、测试环境
VS2008
Python2.5
Boost 1.38
测试工程下载