婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > Python 調用C++封裝的進一步探索交流

Python 調用C++封裝的進一步探索交流

熱門標簽:電銷機器人 金倫通信 鄭州智能外呼系統中心 南京crm外呼系統排名 crm電銷機器人 400電話 申請 條件 賓館能在百度地圖標注嗎 北京外呼電銷機器人招商 云南地圖標注 汕頭電商外呼系統供應商

我們知道,C++和python各有優缺點,C++可以直接映射到硬件底層,實現高效運行,而python能夠方便地來進行編程,有助于工程的快速實現。

那能不能發揮兩者的優勢將它們結合起來?當然是可以的!有多種方法可以實現它們之間的相互轉換。

鏈接文章中,有提到一個簡單的例子,來教我們如何生成可以被python加載的文件。

但是這只能針對簡單的數據進行封裝,一旦涉及到自定義的類等封裝數據,就需要借助第三方庫來幫助更好實現。

比如numpy與C++的數據接口。

這里對python調用C++生成的pyd(so/dll)文件進行進一步的探索。

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

配置為Release平臺,不然numpy的頭文件無法被包含,導致編譯器鏈接出錯。

特別要注意的一點是用cmd生成pyd文件時,VS2013可能要輸入: SET VS90COMNTOOLS=%VS120COMNTOOLS%(每次重新打開cmd窗口運行pythonsetup.py build的時候都要輸入一次)才能生成成功。

2.理解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::AutoBuffernpy_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中Task封裝協程的知識點總結
  • Python自動化測試PO模型封裝過程詳解
  • Python面向對象封裝繼承和多態示例講解
  • Python如何實現Paramiko的二次封裝
  • 使用Python封裝excel操作指南
  • python excel和yaml文件的讀取封裝
  • python 使用paramiko模塊進行封裝,遠程操作linux主機的示例代碼
  • Python之根據輸入參數計算結果案例講解

標簽:懷化 文山 昆明 梅州 錫林郭勒盟 西寧 浙江 石家莊

巨人網絡通訊聲明:本文標題《Python 調用C++封裝的進一步探索交流》,本文關鍵詞  Python,調用,C++,封,裝的,進一步,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《Python 調用C++封裝的進一步探索交流》相關的同類信息!
  • 本頁收集關于Python 調用C++封裝的進一步探索交流的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    av午夜精品一区二区三区| 婷婷成人综合网| 亚洲精品v日韩精品| 国产成人欧美日韩在线电影| 久久蜜桃av一区精品变态类天堂 | 中文字幕亚洲一区二区va在线| 九色porny丨国产精品| 久久久99久久| 91在线免费看| 一区二区视频免费在线观看| 911精品产国品一二三产区| 免费看黄色91| 国产拍欧美日韩视频二区| www.成人在线| 日韩av在线播放中文字幕| 欧美mv和日韩mv的网站| 国产成人久久精品77777最新版本| 中文字幕亚洲在| 欧美一卡二卡在线观看| 国产一区二区日韩精品| 一区二区三区四区乱视频| 日韩一区二区在线观看视频播放| 国产一区二区福利| 亚洲国产欧美在线| 国产精品色在线| 91精品国产色综合久久久蜜香臀| 国产成人av影院| 五月天国产精品| 中文字幕亚洲区| 欧美大度的电影原声| 99精品一区二区三区| 日av在线不卡| 亚洲激情第一区| 中文字幕欧美区| 欧美大片在线观看| 91福利国产成人精品照片| 国产精品一区二区在线观看网站| 亚洲第一搞黄网站| 国产精品久久免费看| 精品欧美乱码久久久久久1区2区 | 国产精品99久| 亚洲午夜一区二区三区| 国产日韩v精品一区二区| 91精品国产手机| 欧美日韩一区不卡| 99精品视频一区二区| 国产在线一区二区综合免费视频| 亚洲成人av资源| 亚洲欧美在线另类| 欧美高清在线视频| 精品国一区二区三区| 欧美日韩免费在线视频| 在线观看一区二区精品视频| av在线一区二区三区| 国产91丝袜在线播放0| 国内成人精品2018免费看| 日本一区中文字幕| 亚洲国产综合在线| 视频在线在亚洲| 午夜成人在线视频| 首页欧美精品中文字幕| 五月天激情综合| 蜜桃视频一区二区三区 | 成人av一区二区三区| 国产精品99久久不卡二区| 国产综合久久久久久久久久久久| 蜜桃视频在线观看一区| 久久爱www久久做| 久久国产麻豆精品| 国产在线播放一区三区四| 国产一区在线视频| 床上的激情91.| 91在线观看美女| 日本精品免费观看高清观看| 在线欧美日韩国产| 欧美挠脚心视频网站| 69堂精品视频| 2021国产精品久久精品| 国产精品你懂的在线欣赏| 亚洲视频狠狠干| 视频在线观看一区二区三区| 激情综合色播五月| 成人avav影音| 欧美久久久一区| 精品日产卡一卡二卡麻豆| 国产精品国产三级国产aⅴ入口 | 性欧美疯狂xxxxbbbb| 日日夜夜精品免费视频| 久久99精品久久久久婷婷| 成人高清视频免费观看| 在线视频综合导航| 欧美成人性战久久| 中文字幕制服丝袜一区二区三区 | 国产不卡在线视频| 色综合网色综合| 欧美精品粉嫩高潮一区二区| 欧美va亚洲va香蕉在线| 国产精品丝袜黑色高跟| 日韩va亚洲va欧美va久久| 国产综合久久久久久鬼色 | 亚洲国产日产av| 日本午夜精品视频在线观看 | 欧美一区二区三区视频在线| 久久久久久久网| 一区二区三区四区乱视频| 麻豆国产91在线播放| 北条麻妃国产九九精品视频| 91麻豆精品91久久久久同性| 国产精品短视频| 美女视频一区在线观看| 91视频在线看| 久久久不卡影院| 蜜臀av一区二区在线免费观看| 91热门视频在线观看| 2021中文字幕一区亚洲| 成人精品视频一区| 欧美日韩高清一区二区不卡| 7777精品伊人久久久大香线蕉经典版下载 | 欧美高清精品3d| 国产精品日韩成人| 国产乱人伦偷精品视频免下载| 91小视频在线| 国产精品另类一区| 国内精品国产成人| 精品人在线二区三区| wwwwww.欧美系列| 亚洲另类在线视频| 国产成人av一区二区三区在线 | 欧美精品第一页| 亚洲在线中文字幕| 色狠狠色噜噜噜综合网| 亚洲欧美乱综合| 91视频com| 亚洲日本在线看| 色婷婷综合久色| 亚洲视频图片小说| 欧美影院午夜播放| 亚洲自拍另类综合| 欧美日韩一区二区三区四区五区| 亚洲自拍偷拍网站| 欧美日韩一区二区不卡| 人禽交欧美网站| 欧美不卡一区二区| 国产麻豆一精品一av一免费| 国产午夜精品一区二区三区四区| 狠狠色丁香婷婷综合| 久久久99久久精品欧美| 精品嫩草影院久久| 精品国产一区二区三区四区四| 一区二区三区日韩在线观看| 91久久精品一区二区三区| 国产精品二区一区二区aⅴ污介绍| 成人永久aaa| 亚洲视频一二三| 在线观看免费成人| 天天综合网 天天综合色| 欧美日韩一区二区在线观看| 亚洲国产裸拍裸体视频在线观看乱了 | 久久激情综合网| 欧美成人性福生活免费看| 国产成人av福利| 亚洲另类在线制服丝袜| www.欧美日韩国产在线| 91女厕偷拍女厕偷拍高清| 国产精品久久久久久久久晋中 | 国产精品久久午夜| 欧洲精品中文字幕| 美国一区二区三区在线播放| 久久亚洲影视婷婷| 色婷婷激情一区二区三区| 午夜精品国产更新| 中文字幕av一区 二区| 在线观看国产日韩| 另类专区欧美蜜桃臀第一页| 亚洲私人影院在线观看| 制服丝袜一区二区三区| 国产福利一区在线观看| 亚洲国产欧美在线| 中文幕一区二区三区久久蜜桃| 在线免费观看一区| 国产一区二区三区国产| 欧美精品日韩精品| 国产不卡视频一区| 亚洲成人在线观看视频| 国产欧美日韩综合| 91麻豆精品国产91久久久久| www.色精品| 国产一区二区三区免费| 亚洲午夜羞羞片| 国产精品国产a级| 日韩欧美黄色影院| 欧美在线观看一区二区| 高清视频一区二区| 激情五月播播久久久精品| 亚洲444eee在线观看| 亚洲美女偷拍久久| 国产精品麻豆99久久久久久| 精品久久五月天| 欧美成人免费网站| 日韩欧美国产1|