使用 ctypes 将 (uint8) NumPy 数组从 python 传递给 c++
Passing a (uint8) NumPy array from python to c++ using 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
(绑定)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.double
并将 const 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 正常工作??
找到了!
我不得不将数组转换为无符号整数,因为 ostream&operator<<(ostream&, unsigned char) 正在打印字符而不是小数。根据 ASCII table,低于 32 的值不代表字符,这就是我在输出中看不到任何内容的原因。
将 indatav[i + cols * j]
更改为 static_cast<unsigned int>(indatav[i + cols * j])
解决了问题!
谢谢!
我已经设法使其适用于双 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
(绑定)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.double
并将 const 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 正常工作??
找到了!
我不得不将数组转换为无符号整数,因为 ostream&operator<<(ostream&, unsigned char) 正在打印字符而不是小数。根据 ASCII table,低于 32 的值不代表字符,这就是我在输出中看不到任何内容的原因。
将 indatav[i + cols * j]
更改为 static_cast<unsigned int>(indatav[i + cols * j])
解决了问题!
谢谢!