一、创建C++工程
1、创建文件准备
- 创建CMakeList文件
cmake_minimum_required(VERSION 2.8.12)
project(hello)
add_subdirectory(pybind11)
pybind11_add_module(hello hello.cpp)
- 创建c++文件
#include <pybind11/pybind11.h>
namespace py = pybind11;
PYBIND11_MODULE(hello, m)
{
m.doc() = "pybind11 example moudle";
m.def("prt", []()
{
return "Hello, World!";
});
}
- 下载pybind11包
将下载的pybind11源码加压并放在项目文件夹下
完成后目录内容如下:
2、cmake编译项目
选择项目目录
此时build目录下如下:
运行hello.sln文件即可打开项目,打开后点击生成
生成了pyd
结尾的hello.cp39-win_amd64.pyd
文件即可在python中直接调用
3、Python导入调用
生成好的.pyd文件还不能直接被python导入,需要放在python能够找到的路径下,即python库包统一存放的位置“**/Lib/site-packages”。如果是用的用的Anaconda自带的python,即直接拷贝放在D:\Anaconda3\Lib\site-packages目录里面了。
放好之后就可以打开python放心调用了:
或者直接放在项目目录下,在项目路径下直接调用
4、从python传递numpy数组到c++处理
C++代码
#include <iostream>
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
namespace py = pybind11;
/*
1d矩阵相加
*/
py::array_t<double> add_arrays_1d(py::array_t<double>& input1, py::array_t<double>& input2 ) {
// 获取input1, input2的信息
py::buffer_info buf1 = input1.request();
py::buffer_info buf2 = input2.request();
if (buf1.ndim != 1 || buf2.ndim != 1)
{
throw std::runtime_error("Number of dimensions must be one");
}
if (buf1.size != buf2.size)
{
throw std::runtime_error("Input shape must match");
}
//申请空间
auto result = py::array_t<double>(buf1.size);
py::buffer_info buf3 = result.request();
//获取numpy.ndarray 数据指针
double* ptr1 = (double*)buf1.ptr;
double* ptr2 = (double*)buf2.ptr;
double* ptr3 = (double*)buf3.ptr;
//指针访问numpy.ndarray
for (int i = 0; i < buf1.shape[0]; i++)
{
ptr3[i] = ptr1[i] + ptr2[i];
}
return result;
}
PYBIND11_MODULE(hello, m)
{
m.doc() = "pybind11 example moudle";
m.def("prt", []()
{
return "Hello, World!";
});
m.def("add_arrays_1d", &add_arrays_1d);
}
python测试代码
var1 = hello.add_arrays_1d(np.array([1, 3, 5, 7, 9]),
np.array([2, 4, 6, 8, 10]))
5、从python传递字符串列表到c++处理
C++代码
#include <pybind11/pybind11.h>
#include <stdio.h>
namespace py = pybind11;
using namespace std;
#if PY_VERSION_HEX < 0x03000000
#define MyPyText_AsString PyString_AsString
#else
#define MyPyText_AsString PyUnicode_AsUTF8
#endif
int run(py::list inlist) {
int argc = (int)inlist.size();
char** argv = (char**)malloc(argc * sizeof(char*));
for (int i = 0; i < argc; ++i)
argv[i] = (char*)MyPyText_AsString(inlist[i].ptr());
for (int i = 0; i < argc; ++i)
fprintf(stderr, "%s\n", argv[i]);
free(argv);
return 0;
}
PYBIND11_MODULE(hello, m)
{
m.doc() = "pybind11 example moudle";
m.def("prt", []()
{
return "Hello, World!";
});
m.def("run", &run, "runs the example");
}
测试结果
参考: