栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【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.04pybind11Anaconda3, with python 3.6cmake

Windows系统

win10 64bitMicrosoft Visual Studio 2017Anaconda3, 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 

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 
#include 

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_(m, "EXClass")
        .def(pybind11::init())
        .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_(m, "SYSZUXav").def(pybind11::init()).def("getframe", &SYSZUXav::getframe);
}

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/779417.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号