博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Win7 VS2017 Boost Python入门
阅读量:6903 次
发布时间:2019-06-27

本文共 3532 字,大约阅读时间需要 11 分钟。

闲来无事想练习下用Python作为游戏脚本绑定到C++,网上搜了下,Python文档有些例子,但是太过复杂,gayhub无意中看到有人用Boost Python绑定,简单粗暴,省时省力,记录备忘。

写本文时使用

boost 1.69

python 3.71

首先在VS中配置好boost和python的include以及lib目录,自不必多说。

然后来个Hello World级别的例子,C++调用py脚本及定义的函数,py脚本调用C++定义的函数

先来C++部分

boost_python_hello.cpp

#include 
#include
using namespace std;using namespace boost::python;#if PY_MAJOR_VERSION >= 3# define INIT_MODULE PyInit_mymoduleextern "C" PyObject* INIT_MODULE();#else# define INIT_MODULE initmymoduleextern "C" void INIT_MODULE();#endifchar const* fun_from_cpp(){ return "fun_from_cpp";}int add_from_cpp(int a, int b){ return (a+b);}int main(int argc, char** argv){ try { Py_Initialize(); object main_module = import("__main__"); object main_namespace = main_module.attr("__dict__"); main_namespace["fun_from_cpp"] = fun_from_cpp; main_namespace["add_from_cpp"] = add_from_cpp; object ignored1= exec_file("hello.py", main_namespace, main_namespace); object ignored2 = exec("show_py()", main_namespace); object ignored3 = exec("add_py_show(9, 8)", main_namespace); //object ignored4 = exec("result = 5 ** 2", main_namespace); int five_squared = extract
(main_namespace["result"]); cout << "result from main_namespace is : " << five_squared << endl; } catch (error_already_set& e) { PyErr_PrintEx(0); return 1; } return 0;}

  

再来py脚本部分

hello.py

def show_py():	print("fun from show_py function")def add_py_show(a, b):	print("fun from add_py_show function")	print(a, "+", b, "=", a+b)def add_py(a, b):	return (a+b)result = 2 * 3result = add_py(1, 2)print(fun_from_cpp())print("add_from_cpp, 4 + 5 = ", add_from_cpp(4, 5))

  

显示结果

fun_from_cppadd_from_cpp, 4 + 5 =  9fun from show_py functionfun from add_py_show function9 + 8 = 17result from main_namespace is : 3

  

需要注意的是,运行时需要python目录在环境变量中,并且

boost_python37-vc141-mt-x32-1_69.dll

boost_python37-vc141-mt-gd-x32-1_69.dll

要放到运行的可执行文件目录下,以防找不到文件导致运行失败。

前者是Release下使用的,后者是Debug下使用的。

 

 

过程分析。

首先exec_file运行了hello.py脚本

object ignored1= exec_file("hello.py", main_namespace, main_namespace);

  

运行后,main_namespace的result 值为3,因为add_py(1, 2)返回值为3

result = add_py(1, 2)

  

然后,在py中调用了两个C++中定义的函数,fun_from_cpp和add_from_cpp

print(fun_from_cpp())print("add_from_cpp, 4 + 5 = ", add_from_cpp(4, 5))

  

接下来C++又调用py中定义的函数

object ignored2 = exec("show_py()", main_namespace);object ignored3 = exec("add_py_show(9, 8)", main_namespace);

  

最后提取py中result的值,并显示

int five_squared = extract
(main_namespace["result"]);cout << "result from main_namespace is : " << five_squared << endl;

  

结果为3

如果把C++部分注释掉的代码解开

object ignored4 = exec("result = 5 ** 2", main_namespace);

  

将影响最终结果,5 * 5 = 25

 

更多例子可以参考boost python的文档

boost_1_69_0\libs\python\index.html

以及gayhub例子

 

 

========================================

今天试了下把程序放到虚似机中运行,测试依赖库,在没装python3.71的时候,直接运行显示缺少python37.dll

把dll复制过去依然不行,接着显示

Fatal Python error: initfsencoding: unable to load the file system codec ModuleNotFoundError: No module named 'encodings'

搜了一下,可以在C++程序中手动指定python目录的方法解决

Py_SetPythonHome(L"./Python37-32");Py_Initialize();

  

这样就可以在无需安装python的情况下运行脚本了,但是目前还是不知道python安装器是怎么做到不用这句话就能正确找到py目录的,虽然安装器装完后在PATH环境变量中有python根目录和Scripts目录,

但是自己手动加入的话还是解决不了这个问题。

 

所以目前先用这个方法好了。

 

说起来python这个体积还是有点大,但是考虑到可以使用python的所有功能或许也值了?

7z单独打包python3.71是22.7 MB,解压后占用90 MB,参考了一下blender目录的python,似乎只要保留bin和lib目录就可以,测试发现的确如此,把py根目录的exe和lib目录留下,其他目录删掉也不影响运行。

当然现在只是简单的例子,只留exe和lib目录大根占用57.8 MB,和90 MB实在相差不多,所以精不精减意义不大。

考虑只用作PC运行,这个体积还算可以接受,最重要的是不用强制安装Python了,简化了一点操作。

 

转载于:https://www.cnblogs.com/kileyi/p/10246013.html

你可能感兴趣的文章
LeetCode 477: Total Hamming Distance
查看>>
win10安装MarkdownPad 2报错This view has crashed的处理及md简单语法
查看>>
Unity3D - 设计模式 - 工厂模式
查看>>
第二十六课:jQuery对事件对象的修复
查看>>
Leetcode题目:Swap Nodes in Pairs
查看>>
Windows聚焦转为图片
查看>>
POJ NOI0101-09 字符菱形
查看>>
jQuery--停止动画和判断是否处于动画状态stop()
查看>>
1-1 接口自动化测试框架从设计到开发
查看>>
MYSQL常用命令
查看>>
js 打开新页面 window.open()
查看>>
Intellij idea 一个窗口打开多模块并添加依赖
查看>>
生成自己的js工具包,包括打包webpack、测试mocha、生成文档jsdoc、发布npm包的操作...
查看>>
企业构建大数据分析体系的4个层级
查看>>
[Linux学习]man page常用按键
查看>>
Django中的CSRF
查看>>
iPhone 物理尺寸与分辨率
查看>>
ios9出现的问题
查看>>
编程之美2.8 | 找符合条件的整数
查看>>
Redhat6.x下如何制作虚拟机快照和镜像封装
查看>>