使用ctypes将(uint8)NumPy数组从python传递到c ++

时间:2018-03-11 03:40:45

标签: python c++ bind wrapper ctypes

我已设法使其适用于双NumPy值,但对于uint8,我没有打印输出。

C ++文件 foo.cpp (对数组进行简单迭代):

#include <iostream>
using namespace std;

extern "C" void cfoo(const uint8_t *indatav, int rows, int cols)
{
    for (int i = 0; i < rows; ++i){
      for (int j = 0; j < cols; ++j){
        cout << "c++ vals --> " << indatav[i + cols * j] << '\n';
      }
    }
}

将其设为共享库:

gcc -lstdc++ -shared -o foo.so foo.cpp

(Bind)Python脚本(将NumPy数组传递给C ++):

import ctypes
import numpy.ctypeslib as ctl
from numpy.ctypeslib import ndpointer
import numpy as np

lib = ctypes.cdll.LoadLibrary("./foo.so")
cfoo = lib.cfoo
cfoo.restype = None
cfoo.argtypes = [ctl.ndpointer(np.uint8, flags='aligned, c_contiguous'), ctypes.c_int, ctypes.c_int]

# Initialize np.array    
pyvals = np.array([[1,2],[3,4]], dtype=np.uint8)
print "pyvals type : ",pyvals.dtype

for i in range (0,pyvals.shape[0]):
    for j in range (0, pyvals.shape[1]):
        print "python vals", pyvals[i,j]

# Call c++ function 
cfoo(pyvals , pyvals.shape[0], pyvals.shape[1]) 

输出(我可以看到cout中没有打印...):

pyvals type :  uint8
python vals 1
python vals 2
python vals 3
python vals 4
c++ vals -->
c++ vals -->
c++ vals -->
c++ vals -->

但是,当我将dtype=np.uint8更改为dtype=np.doubleconst uint8_t *indatav更改为const double *indatav时,我会得到正确的结果:

indata type :  float64
python vals 1.0
python vals 2.0
python vals 3.0
python vals 4.0
c++ vals --> 1
c++ vals --> 3
c++ vals --> 2
c++ vals --> 4

我应该为uint8 numpy.ndarray做些什么改变?

1 个答案:

答案 0 :(得分:0)

发现它!

我必须将数组转换为unsigned int,因为ostream&amp; operator&lt;&lt;(ostream&amp;,unsigned char)正在打印字符而不是小数。根据ASCII表,32以下的值不代表字符,这就是我无法在输出中看到任何内容的原因。

indatav[i + cols * j]更改为static_cast<unsigned int>(indatav[i + cols * j])解决了问题!

谢谢!