Win7 VS2017 Boost Python入门
闲来无事想练习下用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 <iostream>
#include <boost/python.hpp>
using namespace std;
using namespace boost::python;
#if PY_MAJOR_VERSION >= 3
# define INIT_MODULE PyInit_mymodule
extern "C" PyObject* INIT_MODULE();
#else
# define INIT_MODULE initmymodule
extern "C" void INIT_MODULE();
#endif
char 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<int>(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 * 3
result = add_py(1, 2)
print(fun_from_cpp())
print("add_from_cpp, 4 + 5 = ", add_from_cpp(4, 5))
显示结果
fun_from_cpp add_from_cpp, 4 + 5 = 9 fun from show_py function fun from add_py_show function 9 + 8 = 17 result 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<int>(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例子
https://github.com/TNG/boost-python-examples
========================================
今天试了下把程序放到虚似机中运行,测试依赖库,在没装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了,简化了一点操作。
Win7 VS2017 Boost Python入门的更多相关文章
- boost.python入门教程 ----python 嵌入c++
Python语言简介 Python是一种脚本语言.以开放的开发接口和独特的语法著称.尽管Python在国内引起注意只有几年的时间,但实际上Python出现于上世纪90年代(据www.python.or ...
- 64位win7下安装Boost 1.59.0 + boost.python 1.59.0 + gccxml + pygccxml + pyplusplus(py++)
由于安装过程中实在是出现了N多问题,所以不得不专门写个帖子来记录一下这破东西在Win7下的安装过程,避免以后还要再用的时候踩坑. 1.Boost简介 Boost库是一个可移植.提供源代码的C++库,作 ...
- python 入门教程
转载自:http://www.crifan.com/files/doc/docbook/python_beginner_tutorial/release/html/python_beginner_tu ...
- [转]boost::python开发环境搭建
转自:http://www.cnblogs.com/gaoxing/p/4317051.html 本来想用mingw编译boost::python模块,网上看了下资料太少,只有使用vs2012 操作环 ...
- boost::python开发环境搭建
本来想用mingw编译boost::python模块,网上看了下资料太少,只有使用vs2012 操作环境:win7 x64 python: x86 boost: 1.57 编译boost::pytho ...
- win7+cuda+anaconda python+tensorflow-gpu+keras安装成功版本匹配汇总
win7+cuda+anaconda python+tensorflow-gpu+keras安装成功版本匹配汇总 2019-09-20 15:06:03 wyx100 阅读数 38更多 分类专栏: M ...
- boost.python笔记
boost.python笔记 标签: boost.python,python, C++ 简介 Boost.python是什么? 它是boost库的一部分,随boost一起安装,用来实现C++和Pyth ...
- Boost.Python简介
Boost.Python简单概括:是Boost库的一部分:用来在C++代码中调用python代码以及在Python代码中调用C++代码,并且避免用户直接操作指针. 以下内容搬运自:https://wi ...
- python入门简介
Python前世今生 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC ...
随机推荐
- redis数据转移随笔
生产环境有一批版本比较老的redis主从架构,是一主多从,版本是2.8 由于想迁移到阿里云上,那么问题来了,怎么把redis数据转移到阿里云上 为了省事,阿里云也是和生产环境一样的版本,架构也一致,其 ...
- ArcGIS案例教程-通过点坐标生成矩形
ArcGIS案例教程-通过点坐标生成矩形 联系方式:谢老师,135-4855-4328,xiexiaokui#qq.com 功能:以点坐标为中心,通过指定尺寸,生成矩形 成果形式:绿色工具,免安装,不 ...
- jmeter学习笔记--线程组
jmeter组件:线程组 是什么? 进程:一个正在执行的程序对应一个进程 线程:进程中的执行线索(一个进程中有多个执行线索) 线程组:按照线程性质对线程进行分组 并发执行:多个线程同时进行 特点 ...
- python入门(十五):装饰器
1.装饰器(decorator):设计模式 作用:给不同的函数和方法,增加不同的公用的功能. @classmethod,@staticmethod等均是装饰器 定义一个装饰函数,函数必须返回一个闭包函 ...
- Java框架spring 学习笔记(五):Bean定义继承
子 bean 的定义继承父定义的配置数据.子定义可以根据需要重写一些值,或者添加其他值. 编写HelloWorld.java package com.example.spring; public cl ...
- python之字符串及其方法---整理集
字符串方法 1.capitalize方法:字符串首字母大写 举例: test="alex" v=test.capitalize() print(v) 返回结果: Alex 2.ca ...
- ListBox设置背景色无效的问题。 listview类似
<Style TargetType="{x:Type ListBoxItem}"> <Setter Property="Template"&g ...
- 避免切换横竖屏Fragment的重复加载导致UI混乱
当我们切换横竖屏时 Activity的生命周期就会重走一遍,自然 其中的Fragment的生命周期也就重新走了一遍,实践证明 当熄屏 再开屏时 Fragment的生命周期也会重走一遍 解决方案: an ...
- Mapnik 3.0.20编译安装
1. 确定epel安装 yum install -y epel-release 2. 按照<CentOS7.2部署node-mapnik>一文中的步骤,手动安装 gcc-6.2.0 和 b ...
- Qt5.12.2开发Android环境搭建
Qt-Android开发环境概要qt-opensource-windows-x86-5.12.2----armv7jdk-8u201-windows-x64android-ndk-r18b-windo ...