iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >怎么在Python项目中调用C++进行封装
  • 283
分享到

怎么在Python项目中调用C++进行封装

2023-06-06 17:06:01 283人浏览 安东尼
摘要

怎么在python项目中调用c++进行封装?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Python主要用来做什么Python主要应用于:1、web开发;2、数据科学研究;

怎么在python项目中调用c++进行封装?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

Python主要用来做什么

Python主要应用于:1、web开发;2、数据科学研究;3、网络爬虫;4、嵌入式应用开发;5、游戏开发;6、桌面应用开发。

1.首先进行如下配置,在VC++目录中包含python和numpy的文件目录:

怎么在Python项目中调用C++进行封装

配置为Release平台,不然numpy的头文件无法被包含,导致编译器链接出错。

特别要注意的一点是用cmd生成pyd文件时,VS2013可能要输入: SET VS90COMNTOOLS=%VS120COMNTOOLS%(每次重新打开cmd窗口运行pythonsetup.py build的时候都要输入一次)才能生成成功。

2.理解python调用C++的数据交互过程:

怎么在Python项目中调用C++进行封装

Python中的代码通过CPython等将语句解释为C/C++语言,然后编译器调用binding入口函数,将传进来的PyObject*参数通过PyFloat_AsDouble()等转换成C/C++变量。

这些作为输入变量传进已经写好的C++函数,调用该函数,返回C++结果。最后反过来,将C/C++变量转成CPython可以识别的PyObject*对象返回给python编译器(如函数PyFloat_FromDouble()),完成python到C++的调用。

当C/C++里面的输入变量或者返回值都不是基本类型时,比如自定义的类,那我们同样要按照类里面定义数据的方式以数据的方式来对应改成python能识别的基本类型的组合。

以Mat和numpy的array对象相互转换为例:

//以Mat的allocator作为基类,Numpy的Allocator作为继承类//这样可以用派生对象指针对基类数据进行操作class NumpyAllocator : public MatAllocator{public: NumpyAllocator() { stdAllocator = Mat::getStdAllocator(); } ~NumpyAllocator() {}  UMatData* allocate(PyObject* o, int dims, const int* sizes, int type, size_t* step) const {  UMatData* u = new UMatData(this);  u->data = u->origdata = (uchar*)PyArray_DATA((PyArrayObject*) o);  npy_intp* _strides = PyArray_STRIDES((PyArrayObject*) o);  for( int i = 0; i < dims - 1; i++ )   step[i] = (size_t)_strides[i];  step[dims-1] = CV_ELEM_SIZE(type);  u->size = sizes[0]*step[0];  u->userdata = o;  return u; }  UMatData* allocate(int dims0, const int* sizes, int type, void* data, size_t* step, int flags, UMatUsageFlags usageFlags) const {  if( data != 0 )  {   CV_Error(Error::StsAssert, "The data should nORMally be NULL!");   // probably this is safe to do in such extreme case   return stdAllocator->allocate(dims0, sizes, type, data, step, flags, usageFlags);  } //确保当前使用python的C api线程安全的  PyEnsureGIL gil;   int depth = CV_MAT_DEPTH(type);  int cn = CV_MAT_CN(type);  const int f = (int)(sizeof(size_t)/8);  int typenum = depth == CV_8U ? NPY_UBYTE : depth == CV_8S ? NPY_BYTE :  depth == CV_16U ? NPY_USHORT : depth == CV_16S ? NPY_SHORT :  depth == CV_32S ? NPY_INT : depth == CV_32F ? NPY_FLOAT :  depth == CV_64F ? NPY_DOUBLE : f*NPY_ULONGLONG + (f^1)*NPY_UINT;  int i, dims = dims0;  cv::AutoBuffer<npy_intp> _sizes(dims + 1);  for( i = 0; i < dims; i++ )   _sizes[i] = sizes[i];  if( cn > 1 )   _sizes[dims++] = cn;  PyObject* o = PyArray_SimpleNew(dims, _sizes, typenum);  if(!o)   CV_Error_(Error::StsError, ("The numpy array of typenum=%d, ndims=%d can not be created", typenum, dims));  return allocate(o, dims0, sizes, type, step); }  bool allocate(UMatData* u, int accessFlags, UMatUsageFlags usageFlags) const {  return stdAllocator->allocate(u, accessFlags, usageFlags); }  void deallocate(UMatData* u) const {  if(!u)   return;  PyEnsureGIL gil;  CV_Assert(u->urefcount >= 0);  CV_Assert(u->refcount >= 0);  if(u->refcount == 0)  {   PyObject* o = (PyObject*)u->userdata;   Py_XDECREF(o);   delete u;  } } //基类指针,调用allocate函数进行内存分配 const MatAllocator* stdAllocator;};

上面是先构造好能够相互交互的allocator。

//将PyObject的特性幅值给size,ndims,type int typenum = PyArray_TYPE(oarr), new_typenum = typenum; int type = typenum == NPY_UBYTE ? CV_8U :    typenum == NPY_BYTE ? CV_8S :    typenum == NPY_USHORT ? CV_16U :    typenum == NPY_SHORT ? CV_16S :    typenum == NPY_INT ? CV_32S :    typenum == NPY_INT32 ? CV_32S :    typenum == NPY_FLOAT ? CV_32F :    typenum == NPY_DOUBLE ? CV_64F : -1;  //....  int ndims = PyArray_NDIM(oarr); //....  const npy_intp* _sizes = PyArray_DIMS(oarr);  const npy_intp* _strides = PyArray_STRIDES(oarr); for ( int i = ndims - 1; i >= 0; --i ) {  size[i] = (int)_sizes[i];  if ( size[i] > 1 )  {   step[i] = (size_t)_strides[i];   default_step = step[i] * size[i];  }  else  {   step[i] = default_step;   default_step *= size[i];  } } //.... //这一步直接用PyObject初始化Mat m m = Mat(ndims, size, type, PyArray_DATA(oarr), step); m.u = g_numpyAllocator.allocate(o, ndims, size, type, step); m.addref();

上面是将PyObject对象转为Mat的部分代码,具体可以参考OpenCV的cv2.cpp文件:..\OpenCV\sources\modules\python\src2

//将Mat转换为PyObject*template<>PyObject* pyopencv_from(const Mat& m){ if( !m.data )  Py_RETURN_NONE; Mat temp, *p = (Mat*)&m; //确保数据拷贝不会对原始数据m产生破坏 if(!p->u || p->allocator != &g_numpyAllocator) {  temp.allocator = &g_numpyAllocator;  ERRWRAP2(m.copyTo(temp));  p = &temp; } //将Mat封装好的userdata指针转给Pyobject* PyObject* o = (PyObject*)p->u->userdata; //引用计数器加一 Py_INCREF(o); return o;}

3.不是所有C++的语法都能转为python可调用的pyd文件

一个很重要的知识点是,pyd文件跟dll文件非常相似,所以生成dll比较困难的C++代码同样难以生成pyd,C++跟python编译器各自编译特性的区别也会使得转换存在困难,比如C++的动态编译。

下面是可以进行相互转换的C++特性(可以用swig生成):

类;构造函数和析构函数;虚函数;(多重)公有继承;

静态函数;重载(包括大多数操作符重载);引用;

模板编程(特化和成员模板);命名空间;默认参数;智能指针。

下面是不能或者比较困难进行转换的C++特性:

嵌套类;特定操作符的重载比如new和delete。

关于怎么在Python项目中调用C++进行封装问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注编程网其他教程频道了解更多相关知识。

--结束END--

本文标题: 怎么在Python项目中调用C++进行封装

本文链接: https://www.lsjlt.com/news/248177.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 怎么在Python项目中调用C++进行封装
    怎么在Python项目中调用C++进行封装?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Python主要用来做什么Python主要应用于:1、Web开发;2、数据科学研究;...
    99+
    2023-06-06
  • 如何在java项目组中进行封装
    今天就跟大家聊聊有关如何在java项目组中进行封装,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。java 中的封装介绍及使用方法在面向对象程式设计方法中,封装(英语:Encapsul...
    99+
    2023-05-31
    java ava
  • 如何在Java项目中利用post请求对Json进行封装
    如何在Java项目中利用post请求对Json进行封装?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。直接上代码String longUrl = ...
    99+
    2023-05-31
    json java post
  • python调用zxing项目进行二维码
    摘要:首先创建一个java的maven项目,加入zxing相关包,编写二维码相关代码,调试运行,打包;然后创建一个python项目,安装jpype,编写代码把相关的jar包加载,运行。 0. 创建一个maven项目 1. 配置po...
    99+
    2023-01-31
    项目 二维码 python
  • 怎么在python项目中对xml进行解析
    今天就跟大家聊聊有关怎么在python项目中对xml进行解析,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。一、XML的读取import xml.dom.minidom#负责...
    99+
    2023-06-06
  • Java项目中怎么对任务进行调度
    这期内容当中小编将会给大家带来有关Java项目中怎么对任务进行调度,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。简介: 综观目前的 Web 应用,多数应用都具备任务调度的功能。本文由浅入深介绍了几种任务调...
    99+
    2023-05-31
    java ava 目中
  • 如何在C#项目中调用WebApi
    如何在C#项目中调用WebApi?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。1.WebRequest方式Post:private void butto...
    99+
    2023-06-14
  • 在Android应用中怎么对Toast提示进行封装
    在Android应用中怎么对Toast提示进行封装?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Android Toast提示封装Android中经常用到Toa...
    99+
    2023-05-31
    android toast roi
  • 怎么在javaWeb项目中使用Redis进行缓存
    怎么在javaWeb项目中使用Redis进行缓存?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。一:serviceImpl定义:@Service  &nb...
    99+
    2023-05-30
  • JS项目中如何对本地存储进行二次封装
    今天小编给大家分享一下JS项目中如何对本地存储进行二次封装的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。前言平时在开发的中,...
    99+
    2023-07-02
  • PHP中怎么对类进行封装
    PHP中怎么对类进行封装,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。public:方法或者属性在任何作用域都可以访问到,而且这是默认的,如果没有为一个属性或方法指定访问修...
    99+
    2023-06-17
  • vue项目中进行svg组件封装及配置方法步骤
    最近刚入新的公司,拿到项目之后,发现一个有趣的事情就是标题的icon是用svg来弄的,这篇文章彻底弄清楚怎么使用 1.创建vue项目(通过cli来搭建脚手架,该测试项目是用vue...
    99+
    2024-04-02
  • 怎么在C++中调用Python
    小编给大家分享一下怎么在C++中调用Python,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Python的安装为了使用Python.h这个扩展项,我们需要安装一...
    99+
    2023-06-15
  • 如何在vue项目中使用封装后的axios
    这篇文章给大家介绍如何在vue项目中使用封装后的axios,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。为什么要使用VueVue是一款友好的、多用途且高性能的JavaScript框架,使用vue可以创建可维护性和可测试...
    99+
    2023-06-06
  • System.Windows.Interactivity怎么在c# 项目中使用
    这篇文章给大家介绍System.Windows.Interactivity怎么在c# 项目中使用,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。1 引入命名空间  通过在代码中引入System.Windows.Inter...
    99+
    2023-06-06
  • Newtonsoft.Json怎么在c#项目中使用
    本篇文章为大家展示了 Newtonsoft.Json怎么在c#项目中使用,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。1 实体类的 Json 序列化和反序列化我们以如下的 Person 类举例,其中...
    99+
    2023-06-06
  • Android应用中怎么对RecyclerView Adapter进行封装
    本篇文章给大家分享的是有关Android应用中怎么对RecyclerView Adapter进行封装,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。通常我们封装的时候,可以简化到...
    99+
    2023-05-31
    recyclerview adapter android
  • JS项目中对本地存储进行二次的封装的实现
    目录前言定义恒量的键名下层实现上层调用总结前言 平时在开发的中,发现身边同事在使用localStorage和sessionStorage的时候,喜欢在代码里面直接调用,举个的栗子: ...
    99+
    2024-04-02
  • 怎么在java项目中利用mongodb进行查询操作
    本篇文章为大家展示了怎么在java项目中利用mongodb进行查询操作,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。java 中mongodb的各种操作查询的实例详解一. 常用查询: 查询一条数据:...
    99+
    2023-05-31
    java mongodb
  • 怎么在Spring Boot项目中利用JSR-380进行校验
    怎么在Spring Boot项目中利用JSR-380进行校验?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。介绍JSR-380 是 J2EE 的一个规范,用于校验实体属性,它是 ...
    99+
    2023-06-06
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作