- visual studio cpp cmake 开发环境
略 - windos 下python3安装,以及pybind11库安装
略
说明:1. 对于linux货mac 环境需要安装python-dev版本,如python3.9-dev,但在windows环境无 dev版本,直接使用 非dev的常规版本即可,windows常规版本即带有 Python.h 等各种头文件,可以支持python 扩展模块开发 - 源码
#include <iostream>
#include <Python.h>
#include <pybind11/pybind11.h>
namespace py = pybind11;
int add(int a, int b) {
return a + b;
}
std::string hello(std::string someone) {
std::cout << "hello " << someone << std::endl;
return "hello" + someone;
}
// pybind11使用参照pybind11 官方教程即可
PYBIND11_MODULE(pytry, m) {
m.doc() = "pybind11 example in win"; //optional module docstring
m.def("add", &add, "A function that adds two numbers");
m.def("hello", &hello, "A function that hello some one");
}
- 编译
cmake 编译配置
cmake_minimum_required (VERSION 3.8)
project ("CMakeProject1")
set(CMAKE_EXPORT_COMPILE_COMMANDS on) # 输出compile_command.json
set(Python_DIR,"C:/Users/xxxx/AppData/Local/Programs/Python/Python39" ) # 用于设定查找python模块的指定路径
find_package(Python COMPONENTS Interpreter Development) # findpython 可参考 https://cmake.org/cmake/help/v3.12/module/FindPython.html
find_package(pybind11 PATHS "C:/workplace/pythonProject/firstpython/venv/Lib/site-packages/pybind11" ) // 用于给查找指定 pybind11 模块指定路径
message(${Python_FOUND}) # 输出查找结果
message(${pybind11_FOUND}) # 输出查找结果
include_directories(${pybind11_INCLUDE_DIRS}) # include pybind11 和 python的头文件
add_library(pytry SHARED "pytry.cpp") # 必须是生成动态库
target_link_libraries(pytry ${Python_LIBRARIES}) # 链接 python.lib 库
# TODO: 如有需要,请添加测试并安装目标。
说明: 编译时如果提示缺少python39_d.lib 等,复制 python39.lib为 python39_d.lib即可, 或者将vs 的配置由debug 改为为release, 如下图
- 修改生成的动态库文件名
windows中的 识别的动态库后缀必须是.pyd, 复制生成pytry.dll pytry.pyd 即可
说明: 文件名必须与python模块名一致,python模块名在cpp脚本PYBIND11_MODULE部分设定。
生成好的.pyd, 在当前目录下打开python可以直接通过import pytry 导入模块。
- linux 环境下
cmake:
#c++ -O3 -Wall -shared -std=c++11 -fPIC $(python3 -m pybind11 --includes) spam.cpp -o spam.so #命令行执行原始
cmake_minimum_required(VERSION 3.0.0)
project(spam VERSION 0.1.0)
# set(CMAKE_CXX_STANDARD 11)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_CXX_FLAGS "-Wall")
set(CMAKE_CXX_FLAGS "-fPIC")
set(CMAKE_CXX_FLAGS "-std=c++11")
include(CTest)
enable_testing()
#python package find
set(Python3_ROOT_DIR "/home/xxxx/.pyenv/versions/3.9-dev")
find_package (Python3 COMPONENTS Interpreter Development REQUIRED)
find_package(pybind11 CONFIG PATHS "/home/xxxxx/.pyenv/versions/py39dev/lib64/python3.9/site-packages/pybind11" REQUIRE)
message(${Python3_FOUND})
message(${pybind11_FOUND})
# add_subdirectory()
include_directories(${pybind11_INCLUDE_DIRS})
# set(CMAKE_SHARED_LIBRARY_PREFIX "")
# set(CMAKE_STATIC_LIBRARY_PREFIX "")
add_library(spam SHARED spam.cpp)
# set_target_properties(spam PROPERTIES SUFFIX "_add") # 目标文件前缀
# set_target_properties(spam PROPERTIES SUFFIX "_add") # 目标文件后缀
# set_target_properties(spam PROPERTIES RELEASE_PREFIX "") # 可执行文件后缀
# add_executable(spam_ spam.cpp)
# pybind11_add_module(spam spam.cpp)
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)
linux下python对动态库的识别,文件名后缀为.so, 文件名必须和模块名一致,即不能带有lib前缀。