C++编写Python模块 第一篇

  • 概述
  • 目标
  • 环境
  • 软件及依赖库
  • 安装
  • 第一个Hello,World Python模块示例
  • 工程目录树
  • 源文件
  • CMake配置文件
  • hello/CMakeLists.txt
  • hello/src/CMakeLists.txt
  • 构建工程
  • 编译生成
  • Python调用
  • 后续


概述

网上已经又很多得这样得文章, 我写该文章得主要目的是一步一步的实现,致力于读者能看完该博客后能动手实现一个可以运行的程序实例

目标

  1. 构建一个生成python模块的Hello,World工程
  2. 基于第一个工程实现封装C++类的python模块
  3. 基于第二个工程实现将C++动态库也封装为可以供python调用的python模块
  4. 在C++中调用python解释器执行python代码,python代码中调用自己编写的python模块

环境

  • windows 7

软件及依赖库

  • vs2013
  • cmake 3.12
  • python27(64位)
  • boost_1_70_0

安装

  • 软件下载完成后直接按照默认的路径和设置安装完成即可
  • 注意: 如果不想编译boost,可以直接网上找编译好的boost的可执行程序进行安装,例如:boost_1_70_0-msvc-12.0-64.exe 这样的安装包
  • boost_1_70_0下载网址:https://sourceforge.net/projects/boost/files/boost-binaries/1.70.0/

第一个Hello,World Python模块示例

  • 该示例会使用Cmake生成VS工程
  • 使用默认安装boost的话, boost会安装在C:/local/boost_1_70_0
  • 本例子使用boost库中自带的C++代码生成python模块的示例
  • 自带的代码在C:/local/boost_1_70_0/libs/python/example/tutorial目录下

工程目录树

  • hello(工程根目录)
  • build(目录)
  • src(目录)
  • CMakeLists.txt(文件)
  • hello.cpp(文件)
  • CMakeLists.txt(文件)

源文件

  • 可以将C:/local/boost_1_70_0/libs/python/example/tutorial下的hello.cpp文件拷贝到hello/src的工程目录下, 代码如下:
//  Copyright Joel de Guzman 2002-2004. Distributed under the Boost
//  Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt
//  or copy at http://www.boost.org/LICENSE_1_0.txt)
//  Hello World Example from the tutorial
//  [Joel de Guzman 10/9/2002]

#include <boost/python/module.hpp>
#include <boost/python/def.hpp>

char const* greet()
{
   return "hello, world";
}

BOOST_PYTHON_MODULE(hello_ext)
{
    using namespace boost::python;
    def("greet", greet);
}

CMake配置文件

hello/CMakeLists.txt
cmake_minimum_required(VERSION 2.8)

# 设置工程名称
project(boost_python_hello)

add_definitions(
-D_CRT_SECURE_NO_WARNINGS
)

# 搜索python2的头文件目录和库文件目录
find_package (Python2 COMPONENTS Interpreter Development)
include_directories(${Python2_INCLUDE_DIRS})
link_directories(${Python2_LIBRARY_DIRS})

# 搜索Boost的头文件目录和库文件目录
# 搜索Boost python库
set(Boost_USE_STATIC_LIBS       OFF) # only find static libs
set(Boost_USE_MULTITHREADED      ON)
set(Boost_USE_STATIC_RUNTIME    OFF)
find_package(Boost COMPONENTS python27)
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})

# 执行子目录里的CMake配置文件
add_subdirectory(src)
hello/src/CMakeLists.txt
# 包含该目录的头文件
set(CMAKE_INCLUDE_CURRENT_DIR ON)

# 生成动态库hello_ext.dll
add_library(hello_ext SHARED hello.cpp)

# hello_ext.dll 动态库依赖boost中的python库
# 所以需要链接Boost中的 boost_python27-*.lib
target_link_libraries(hello_ext ${Boost_LIBRARIES})

构建工程

使用C++开发python 扩展库 c++编写python库_python模块

  • 打开带界面的CMake软件
  • 选择source code目录为"hello"目录
  • 选择build the binaries目录为"hello/build"目录
  • 点击"Configure"
  • 选择 Visual Studio 12 2013 Win64
  • 点击"Finish"
  • 注意:这里可能会出现错误提示 “Could NOT find Boost”
  • 这是没有找到boost的根目录
  • 点击"Add Entry"按钮设置以下选项:
  • Name: BOOST_ROOT
  • Type: PATH
  • Value: 这里选择boost的根目录,例如 C:/local/boost_1_70_0
  • 继续点击"Configure"
  • 点击"Generate"按钮生成VS2013的工程
  • 点击"Open Project"打开VS2013工程

编译生成

  • 选择 Relase X64
  • 构建工程
  • 这时会在"build\src\Release"目录下生成 "hello_ext.dll"动态库
  • 到此就完成了使用boost生成python模块的全部流程了

Python调用

  • 打开工程目录"build\src\Release"
  • 由于生成该Python模块使用了Boost的库,所以应该把boost的库也复制到该目录下
  • 将"boost_1_70_0/lib64-msvc-12.0/boost_python27-*.dll"复制过来
  • 将工程目录下的"hello_ext.dll"改名为"hello_ext.pyd"
  • 在工程目录"build\src\Release"下打开命令行
  • 注意:将命令行的路径切换到当前路径
  • 输入"C:\Python27\python.exe"回车
# python命令行中输入以下命令
import hello_ext
hello_ext.greet()
  • 如果一切顺利就会输出’hello,world’的字样了

后续

至此, 我们就完成构建一个生成python模块的Hello,World工程的目标了,之后的实现会在C++编写Python模块 第二篇中实现.