【PyBind11+anaconda+opencv+windows11+cmake+wsl+vscode】从入门到跑通。构建基于opencv c++的python接口

前言

为了使用C++ 编写python的扩展程序, 需要使用pybind11, pybind11使用比较简单,文档也比较详细。下面本人Windows系统上测试使用pybind11,本篇主要讲述简单样例与原理.平常使用的python实现都是cpython,所以使用C语言或者C++来写一些扩展的时候,就相当于在写cpython的插件。cpython的扩展关键在于要实现一个PyObject* PyInit_modulename(void)的函数,也叫initialization function,这个函数返回一个PyModuleDef 的instance。


开发/测试环境

Ubuntu系统

  • Ubuntu 18.04
  • pybind11
  • Anaconda3, with python 3.6
  • cmake

Windows系统

  • win10 64bit
  • Microsoft Visual Studio 2017
  • Anaconda3, with python 3.7

Pybind11

GitHub - pybind/pybind11: Seamless operability between C++11 and Python


安装配置

下载pybind11或者直接pip install pybind11
git clone https://github.com/pybind/pybind11.git

简单样例

添加一个c++ add算子

//ex.cpp
#include <pybind11/pybind11.h>

int add(int i, int j) {
    return i + j;
}

PYBIND11_MODULE(ex, m) {
    m.doc() = "pybind11 example plugin"; // optional module docstring
    m.def("add", &add, "A function which adds two numbers");
}

编译为so动态链接库,供pythonimport调用

#该编译命令会生成 ex.cpython-35m-x86_64-linux-gnu.so
g++ -O3 -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` ex.cpp -o gemfield`python3-config --extension-suffix`

python测试

>>> import ex
>>> ex.add(1,1)
2

那么看看PYBIND11_MODULE的宏展开之后执行了什么。

可以看到实现了PyObject *PyInit_ex()函数。

static void pybind11_init_ex(pybind11::module &); 
extern "C" __attribute__ ((visibility("default"))) PyObject *PyInit_ex() { 
    { 
        const char *compiled_ver ="3.8"; 
        const char *runtime_ver = Py_GetVersion(); 
        size_t len = std::strlen(compiled_ver); 
        if (std::strncmp(runtime_ver, compiled_ver, len) != 0 || (runtime_ver[len] >= '0' && runtime_ver[len] <= '9')) { 
            PyErr_Format(PyExc_ImportError, "Python version mismatch: module was compiled for Python %s, " "but the interpreter version is incompatible: %s.", compiled_ver, runtime_ver); 
            return nullptr; 
        } 
    } 
    auto m = pybind11::module("ex"); 
    try { 
        pybind11_init_ex(m); 
        return m.ptr(); 
    } catch (pybind11::error_already_set &e) { 
        PyErr_SetString(PyExc_ImportError, e.what()); 
        return nullptr; 
    } catch (const std::exception &e) { 
        PyErr_SetString(PyExc_ImportError, e.what()); 
        return nullptr; 
    } 
}

void pybind11_init_ex(pybind11::module &m){
    m.doc() = "pybind11 example plugin";
    m.def("add", &add, "A function which adds two numbers");
}

面向对象编写类

如何对c++类进行python绑定呢

#include <pybind11/pybind11.h>
#include <iostream>

extern "C" bool initav(const char* url);
class EXClass{
    public:
        EXClass(const std::string &url) : url(url){initav(url.c_str());}
        const std::string &getFrame() const;

    private:
        std::string url;
};

const std::string& EXClass::getFrame() const
{
    std::cout<< url << std::endl;
    return url;
}

PYBIND11_MODULE(cxvlass, m) {
    pybind11::class_<EXClass>(m, "EXClass")
        .def(pybind11::init<const std::string &>())
        .def("getFrame", &SYSZUXav::getFrame);
}

编译

g++ -O3 -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` syszuxav.cpp -o syszuxav`python3-config --extension-suffix`

同样展开宏查看,可以看到还是实现了

可以看到实现了PyObject *PyInit_exclass()函数。

extern "C" bool initav(const char* url);
class EXClass{
    public:
        EXClass(const std::string &url) : url(url){initav(url.c_str());}
        const std::string &getFrame() const;

    private:
        std::string url;
};

const std::string& EXClass::getFrame() const
{
    std::cout<< url << std::endl;
    return url;
}

static void pybind11_init_exclass(pybind11::module &); 
extern "C" __attribute__ ((visibility("default"))) PyObject *PyInit_exclass() 
{ 
    { 
        const char *compiled_ver = "3.8"; 
        const char *runtime_ver = Py_GetVersion(); 
        size_t len = std::strlen(compiled_ver); 
        if (std::strncmp(runtime_ver, compiled_ver, len) != 0 || (runtime_ver[len] >= '0' && runtime_ver[len] <= '9')) { 
            PyErr_Format(PyExc_ImportError, "Python version mismatch: module was compiled for Python %s, \
                    but the interpreter version is incompatible: %s.", compiled_ver, runtime_ver); 
            return nullptr;
        } 
    } 
    auto m = pybind11::module("exclass"); 
    try { 
        pybind11_init_exclass(m); 
        return m.ptr(); 
    } catch (pybind11::error_already_set &e) { 
        PyErr_SetString(PyExc_ImportError, e.what()); 
        return nullptr; 
    } catch (const std::exception &e) { 
        PyErr_SetString(PyExc_ImportError, e.what()); 
        return nullptr; 
    } 
} 
void pybind11_init_syszuxav(pybind11::module &m)
{
    pybind11::class_<SYSZUXav>(m, "SYSZUXav").def(pybind11::init<const std::string &>()).def("getFrame", &SYSZUXav::getFrame);
}

后续将会结合pip setup+opencv详细说明如何构建python package c++

  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
PyCharm是一种集成开发环境(IDE),可以用于Python开发。Anaconda是一个Python发行版,包含了许多常用的科学计算库和工具。Python是一种用的编程语言,常用于开发各种应用程序。OpenCV是一个开源的计算机视觉库,用于处理图像和视频数据。PyQt是Python的一个GUI库,用于创建图形用户界面。在上述引用中,提到了使用PyCharm和Anaconda来配置和管理PythonOpenCV和PyQt的开发环境。过安装Anaconda,我们可以方便地使用其中的Python版本、OpenCV和PyQt库,而无需单独下载和配置它们。同时,PyCharm也可以与Anaconda集成,使得开发过程更加便捷。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [2020新版pycharm+anaconda+python+opencv+qt环境配置](https://download.csdn.net/download/weixin_38700430/13749822)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatgptT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [pycharm+anaconda+opencv+pyqt环境配置](https://blog.csdn.net/zong596568821xp/article/details/118028155)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatgptT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

子韵如初

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值