Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将Numpy数组传递给C函数进行输入和输出_Python_Numpy_Ctypes_Ffi - Fatal编程技术网

Python 将Numpy数组传递给C函数进行输入和输出

Python 将Numpy数组传递给C函数进行输入和输出,python,numpy,ctypes,ffi,Python,Numpy,Ctypes,Ffi,噢,我的天,我是个傻瓜。 调用函数时,我只是省略了第二个和第三个参数。 像个傻瓜。 因为我就是这样。 原始问题如下: 这似乎是一件非常常见的事情,但我找不到相关的教程,而且我对Numpy和ctypes太无知了,自己也弄不清楚 我在文件ctest.C中有一个C函数 #包括 void cfun(常量void*indatav、int rowcount、int colcount、void*outdatav){ //void cfun(常量double*indata、int rowcount、int co

噢,我的天,我是个傻瓜。 调用函数时,我只是省略了第二个和第三个参数。 像个傻瓜。 因为我就是这样。 原始问题如下:

这似乎是一件非常常见的事情,但我找不到相关的教程,而且我对
Numpy
ctypes
太无知了,自己也弄不清楚

我在文件
ctest.C
中有一个C函数

#包括
void cfun(常量void*indatav、int rowcount、int colcount、void*outdatav){
//void cfun(常量double*indata、int rowcount、int colcount、double*outdata){
常数double*indata=(double*)indatav;
double*outdata=(double*)outdatav;
int i;
放置(“我们开始了!”);
对于(i=0;i
(正如您可能猜到的,我最初的参数是double*而不是void*,但我不知道在Python方面该怎么做。我当然很想把它们改回去,但只要它有效,我就不挑剔。)

我用它建立了一个共享的图书馆。 gcc-fPIC-shared-o ctest.so ctest.c

在Python中,我有几个numpy数组,我想把它们传递给C函数,一个作为输入,一个作为输出

indata = numpy.ones((5,6), dtype=numpy.double)
outdata = numpy.zeros((5,6), dtype=numpy.double)
lib = ctypes.cdll.LoadLibrary('./ctest.so')
fun = lib.cfun
# Here comes the fool part.
fun(ctypes.c_void_p(indata.ctypes.data), ctypes.c_void_p(outdata.ctypes.data))

print 'indata: %s' % indata
print 'outdata: %s' % outdata
这不会报告任何错误,但会打印出来

>>> Here we go!
Done!
indata: [[ 1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.]]
outdata: [[ 0.  0.  0.  0.  0.  0.]
 [ 0.  0.  0.  0.  0.  0.]
 [ 0.  0.  0.  0.  0.  0.]
 [ 0.  0.  0.  0.  0.  0.]
 [ 0.  0.  0.  0.  0.  0.]]

outdata数组没有被修改。事实上,如果我再次调用该函数,我会得到一个segfault。这并不奇怪——我真的不知道我在这里做什么。有人能给我指出正确的方向吗?

只需将所有四个参数都传递给C函数。将Python代码更改为:

fun(ctypes.c_void_p(indata.ctypes.data), ctypes.c_void_p(outdata.ctypes.data))
致:


虽然不是对原始问题的直接回答,但这里有一种更方便的调用函数的方法。首先,使C函数的原型与普通C中的原型完全相同。因为不需要分别使用
rowcount
colcount
,我将它们折叠为一个
size
参数:

void cfun(const double *indatav, size_t size, double *outdatav) 
{
    size_t i;
    for (i = 0; i < size; ++i)
        outdatav[i] = indatav[i] * 2.0;
}
现在,调用函数将非常方便:

indata = numpy.ones((5,6))
outdata = numpy.empty((5,6))
fun(indata, indata.size, outdata)
def wrap_fun(indata, outdata):
    assert indata.size == outdata.size
    fun(indata, indata.size, outdata)
您还可以定义一个包装器,使其更加方便:

indata = numpy.ones((5,6))
outdata = numpy.empty((5,6))
fun(indata, indata.size, outdata)
def wrap_fun(indata, outdata):
    assert indata.size == outdata.size
    fun(indata, indata.size, outdata)

我没有在C中调用该函数。我需要吗?抱歉。似乎您正在混合
C
python
并且我不知道它是如何工作的。事实上
放在
C
中调用表明它是从
python
代码调用的。但我怀疑您传递给
C
函数的内容导致了e问题。如果数组是非连续的,您可能需要
numpy.ascontiguousarray()
,例如,.@J.F.Sebastian:您可以向
ndpointer()
调用添加
flags=“C_contracting”
,以动态检查数组是否是C连续的。(也许我应该将此添加到这个答案中。)<代码>标志< /代码>参数导致<代码> TypeError < /代码>如果输入数组不是连续的.@ j.f.SEBASTAN:这就是我试图暗示的,它会添加动态类型检查。您认为TypeError是正确答案吗?