花之剑'HOME

一朵飘舞在风中的雪花,挣扎着,不想被融化。

Boost pyhton c++ 内嵌扩展

Posted on 2008-10-16 15:38 花之剑 阅读(1357) 评论(2)  编辑  收藏 所属分类: c/c++ & algorithm
 

Boost pyhton 内嵌扩展
作者:方剑斌 时间:2008-10-16  Email:fangjianbin@gmail.com

 C++扩展Python

这几天开始研究Boost python,因为项目需要,要采用pyhton作为游戏服务器的脚本处理语言。由于之前没有接触过python,所以学习起来非常费劲,其实学什么都一样,万事开头难嘛。

在学习Boost Python之前呢,我想先了解了解Python,到底是什么东西。大家可以看看介绍http://baike.baidu.com/view/21087.htm

在网上下了一个pyhton2.4的软件,安装后,开始了我的python学习。

先写个hello world吧。

很简单 print "hello world",就是这么简单,python是一门解释型语言,无需编译,非常的方便。

接着,就是复杂的和Boost相关的东西了,整得我非常头疼,而且网上相关资料非常的少,让我很是郁闷。

首先,下载1.36版本的Boost,进入控制台,进入到boost根目录,然后运行

bjam "-sVC80_ROOT=D:\Program Files\Microsoft Visual Studio 8\VC" "-sTOOLS=vc-8_0"  --with-python stage (只编译python库),编译boost::python库,如果不出错的话,在bin.v2下面将生成一个python的文件夹,编译完成后,这里将可以找到Boost::python相关的库文件和dll。编译完之后,将这些dll和lib文件拷贝到C\PlatformSDK\Lib下面,以后就不用再设置库目录了。

完成之后,我进入到boost python的目录,里面有一个example,我用bjam运行之后,发现怎么也不好用,怎么也编译不出。Pyd文件出来,费了好几天,网上也没有相关的资料。

后来,我放弃了这种用bjam的编译方法,决定自己写一个c++工程来编译,我参考了

http://www.builder.com.cn/2008/0530/893201.shtml这篇文章,建立了一个dlld工程,来对python做扩展。写了一个很简单的hello world

char const* greet()

{

 return "hello python";

}

int get()

{

 int a = 10;

 a++;

 return a;

}

BOOST_PYTHON_MODULE(PythonDll)

{

 boost::python::def("greet",greet);

 boost::python::def("get",get);

}

编译成功后,生成了一个PythonDll.dll文件,注意,工程文件必须要和你导出的模块文件同名。

然后,将PythonDll.dll改名为Python.pyd文件,这是一个不模块文件后缀名,必须这样才能被python载入,很变态。

建立一个 test.py文件,

Import PythonDll

Print PythonDll.greet()

Print PythonDll.get()

你将会看到输出:

hello python 

11

这就是简单的Boost python运用,这里是用c++为python写扩展。

接下来,我们再来看看更为复杂的扩展形式,我相信,大家用c++,用的最多的应该就是对象了,如果对象不能导出来,用python就毫无意义了,多说无益,我们继续。

Python是完全面向对象的,在python中,任何东西都是一个对象.大家可以看看<<python 核心编程>>

我们先来写一个c++类吧.我们生成一个PythonDll项目,设置成动态链接库。

加入以下代码

Class Player

{

public:

 Player(int height,int age):

   _height(height),_age(age){}

 

   void SetHeight(int hei)

   {

    _height = hei;

   }

   int GetHeight() const

   {

    return _height;

   }

   void SetAge(int age)

   {

    _age = age;

   }

   int GetAge() const

   {

    return _age;

   }

private:

 int _height;

 int _age;

};

这是一个c++类,有构造函数,方法,属性,我们将要在python中使用它。

现在我们将c++对象用Boost::python导出来.

BOOST_PYTHON_MODULE(PythonDll)

{

 class_<Player>("Player",init<int,int>()) //导出构造函数和参数init<int,int>为参数列表

  .def("SetHeight",&Player::SetHeight)

  .def("GetHeight",&Player::GetHeight)

  .def("SetAge",&Player::SetAge)

  .def("GetAge",&Player::GetAge)

  .def_readonly("Height",&Player::_height)

  .def_readonly("Age",&Player::_age)

;

}

导出的模块名字必须和工程名字一样,大家可以在配置选项中将导出的文件改成Python.pyd。因为Python只能import pyd文件,不知道为什么。。。

然后我们编译工程,将会生成一个Python.pyd文件。

接着我们创建一个python脚本文件,写入以下代码

import PythonDll;

player = PythonDll.Pla(178,24);

print "Yout age =%d"%player.GetAge();

print "Yout height =%d"%player.GetHeight();

print "i will set your age and height";

player.SetHeight(170);

player.SetAge(15);

print "Yout age =%d"%player.GetAge();

print "Yout height =%d"%player.GetHeight();

输出结果为:

Yout age =24

Yout height =178

i will set your age and height

Yout age =15

Yout height =170

之前讲的是用c++做python的扩展,用的都是用c++封装成一个dll,我以为python只能调用c++写的dll扩展,今天在exe工程中写了一个扩展,导出pyd后,用python一测,发现原来也是可以的,兴奋一下下。

那么接下来就会轻松些了,我最近一直在研究,如何让python和c++非常自由的(就像lua)调用呢?

C++ 内嵌Pyhton

下面的例子是从boost文档中来的:

#include <iostream>

#include <string>

#include <boost/python.hpp>

#include <boost/ref.hpp>

#include <vector>

using namespace boost::python;

void greet()

{

    object main = import("__main__");

    object global(main.attr("__dict__"));

    // Define greet function in Python.

    object result = exec(

        "def greet(a):               \n"

        "    return 'Hello %s from Python!' % a \n",

        global, global);

    object greet = global["greet"];

    list lst;

    lst.append(1);

    lst.append(2);

    object r = greet(lst);

    std::string message = extract<std::string>(r);

    std::cout << message << std::endl;

}

int _tmain(int argc, _TCHAR* argv[])

{

    Py_Initialize();

    greet();

    system("Pause");

    return 0;

}

以上的代码是C++内嵌python的简单代码,该代码内嵌了一小段python代码,然后调用并且执行。

当然我们还可以将整个python文件装载进来,里面的文件可以任意的调用,看一个例子。

C++:

 Py_Initialize();

  // Retrieve the main module.

  main = import("__main__");

  // Retrieve the main module's namespace

  global = main.attr("__dict__");

  // Define greet function in Python.

  result = exec_file("test.py",

   global, global);

//调用python中的变量

  std::cout<<"number="<< extract<int>(global["number"])<<endl; 

  //调用python的test方法,并传入参数给python

int a = extract<int>(global["test"](10));

Test.py文件

import kengine_test;

number = 65;

def test(a):

 print a;

return a;

输出结果为:65 10

C++与python自由交互(内嵌和扩展)

做为脚本语言,能够实现自由交互(内嵌和扩展)是非常不错的事情,上面讲的两节,分别介绍了c++扩展python和c++内嵌python,那么接下来,我们将介绍如果实现c++和python的自由交互。也就是集内嵌和扩展并用,这在游戏开发是比较重要的。

看个例子

C++文件。

class Player

{

public:

 Player(int height,int age): _height(height),_age(age){}

   void SetHeight(int hei) { _height = hei;}

   int GetHeight() const { return _height;}

   void SetAge(int age){  _age = age;}

   int GetAge() const {  return _age;}

public: int _height;

 int _age;

};

vector<Player*> g_PlayerList;

void AddPlayer(int height,int age)

{

 Playerpl = new Player(height,age);

 g_PlayerList.push_back(pl);

}

void ClearPlayer()

{

 vector<Player*>::iterator itr = g_PlayerList.begin();

 while (itr != g_PlayerList.end())

 {

  delete *itr;

  itr++;

 }

 g_PlayerList.clear();

}

BOOST_PYTHON_MODULE(kengine_test)

{

 def("AddPlayer",AddPlayer);

 def("GetPlayerCount",GetPlayerCount);

 def("ClearPlayer",ClearPlayer);

}

Int main()

{

 try

 {

  Py_Initialize();

  main = import("__main__");

  global = main.attr("__dict__");

  result = exec_file("test.py",

   globalglobal);

 }catch(std::exceptione)

{

std::cout<<e.what()<<endl;

}

 //调用python中定义的CreatePlayer()

Bool res = extract<bool>(global["CreatePlayer"](10,20));

Std::out<<"玩家个数"<<GetPlayerCount()<<endl;

Return 0;

}

Python文件

Import kengine_test;

def Createplayer(height,age):

Kengine_test.AddPlayer(height,age);

Return true;

输出结果:玩家个数1

Feedback

# re: Boost pyhton c++ 内嵌扩展[未登录]  回复  更多评论   

2011-01-28 19:38 by aa
剑斌,没想到还能在这看到这个文档!真不容易!

# re: Boost pyhton c++ 内嵌扩展  回复  更多评论   

2012-08-03 15:29 by rosehack
我只是想问下,你最后一个例子import 的kengine_test 有效?我的一直是找不到模块kengine_test;

只有注册用户登录后才能发表评论。


网站导航: