VS2019调用boost.Python

生成可执行文件

  1. 新建 Cmake 工程;
  2. 输入以下代码:
#include <boost/python.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/to_python_converter.hpp>
#include <iostream>
using namespace std;
void dummyFunc() {
    cout << "call OK!" << endl;
}
int main()
{
    dummyFunc();
    return 0;
}
  1. CMakeLists.txt中添加头文件目录和库文件目录
# 添加头文件目录
include_directories("D:/work/workspace/carla/Build/boost-1.80.0-install/include")
include_directories("C:/Users/Administrator/AppData/Local/Programs/Python/Python37/include")
# 添加库文件目录
link_directories("C:/Users/Administrator/AppData/Local/Programs/Python/Python37/libs")
# 还是缺少 libboost_python37-vc142-mt-gd-x64-1_80.lib
link_directories("D:/work/workspace/carla/Build/boost-1.80.0-install/lib_no_prefix")
  1. 到boost安装目录下,进入 lib文件夹下,找到前缀是libboost_python37-vc142-mt-x64-1_80.lib文件(前缀有lib),将其前缀的lib删除即可(即重命名为boost_python37-vc142-mt-x64-1_80.lib)。

  2. 生成解决方案,会生成exe文件,如果不可以在vs中直接执行,将工具栏中的当前文档改为*.exe

生成Python调用的库

  1. 新建hello_exe.cpp,注意文件名必须为模块名:
// 参考:https://developer.aliyun.com/article/1260043

// 当引入 #include <boost/python/xxx> 时,Boost 会默认链接 boost_python 动态链接库,
// 如果我们想要链接静态链接库,就需要在 include 之前加上 #define BOOST_PYTHON_STATIC_LIB
// 指定链接 boost_python 的静态库,而不是默认的动态库。
#define BOOST_PYTHON_STATIC_LIB

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

using namespace std;

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

BOOST_PYTHON_MODULE(hello_ext)
{
    using namespace boost::python;
    def("greet", greet);
}
  1. 新建CMakeLists.txt
cmake_minimum_required (VERSION 3.8)

# 添加头文件目录
include_directories("D:/work/workspace/carla/Build/boost-1.80.0-install/include")
include_directories("C:/Users/Administrator/AppData/Local/Programs/Python/Python37/include")
# 添加库文件目录
link_directories("C:/Users/Administrator/AppData/Local/Programs/Python/Python37/libs")
# 还是缺少 libboost_python37-vc142-mt-gd-x64-1_80.lib
link_directories("D:/work/workspace/carla/Build/boost-1.80.0-install/lib_no_prefix")

# 将源代码添加到此项目的可执行文件。
# add_executable (boost_demo "boost_demo.cpp" "boost_demo.h")

# # 生成动态库(共享库)共享库则只有一个副本
add_library(hello_ext SHARED hello_ext.cpp)
#(boost_demo 是库的名字),这条命令告诉cmake,我们想把 boost_demo.cpp编译成一个叫作“boost_demo”的库。
set_target_properties(hello_ext PROPERTIES SUFFIX ".pyd")

构建后会生成hello_ext.pyd

  1. 在生成的.pyd目录下新建hello.py
import hello_ext

print(hello_ext.greet())

从Python中调试*.cpp

  1. 在原始.py脚本中添加打印进程号的代码,并使调试停止于cpp函数调用之前。
import os

# 获取当前进程ID(便于调试)
process_id = os.getpid()
print("Current process id is: ", process_id)

import hello_ext

print(hello_ext.greet())
  1. 在visual studio 中添加断点,并附着到第1步的进程中。

  2. *.py中继续执行,会在vs中暂停。

whl安装包的调式

参考链接 ,转至目录carla\PythonAPI\carla,运行pip install -e .,在Python37\Lib\site-packages\easy-install.pth文件中生成指向源代码的路径。

-e--editable:这个选项表示以“可编辑”模式安装包。在这种模式下,包的源代码可以在本地进行修改,并且这些修改会立即反映到系统中该包的行为上,无需重新安装。这对于开发和调试非常有用。 在当前目录下安装一个包,并创建一个软连接引用该包(而不是将包复制到 site-packages 目录下)。这个软连接是一个指向包代码的符号链接,它可以使包的修改直接反映到当前目录下的项目中,从而方便开发和调试。

解释

setup.py

参数 说明
ext_modules 用于构建 C++ 扩展扩展包,其是 Extension 实例的列表,每一个 Extension 实例描述了一个独立的扩展模块,扩展模块可以设置扩展包名、源文件source、头文件include_dirs、链接库及其路径library_dirs、编译参数extra_compile_args、链接参数extra_compile_args、依赖depends等。
package_dir={'': 'source'} “root package” 中的模块都在 source 目录中
packages=['carla'] 需要处理的包目录(包含了一些.cpp文件)

GLI

全局解释器锁 (GLI,Global Interpreter Lock):在调用外部代码(如C、C++扩展函数)的时候,GIL将会被锁定,直到这个函数结束为止(由于期间没有python的字节码运行,所以不会做线程切换)。