使用 CFFI 将多个 numpy 数组传递给 C

Passing multiple numpy arrays to C using CFFI

我有以下(在现实生活中,C代码要复杂得多,我不想更改它。它到处都使用全局变量)。:

from cffi import FFI

ffibuilder = FFI()

ffibuilder.set_source(
    "mymodule",
    r"""
    #include <stdio.h>

    float *x, *y, *z;
    int n;

    void some_func(){
        int i;
        for(i==0; i<n; i++) printf("%f %f %f\n", x[i], y[i], z[i]);
    }
    """
)

ffibuilder.cdef(
    """
    float *x, *y, *z;
    int n;
    void some_func();
    """
)

if __name__=="__main__":
    ffibuilder.compile()

    from mymodule import ffi, lib
    import numpy as np

    n = 4
    lib.n = n

    for i, k in enumerate(['x','y', 'z']):
        v = i*np.arange(n, dtype=np.float32)
        v.__repr__() # Need to do this for some reason!!
        setattr(lib, k, ffi.cast('float*', ffi.from_buffer(v)))

    lib.some_func()

预期的打印输出(来自 some_func)是:

0.000000 0.000000 0.000000
0.000000 1.000000 2.000000
0.000000 2.000000 4.000000
0.000000 3.000000 6.000000

这确实是我得到的。但是,如果我取出调用 v.__repr__() 的行,我会得到以下内容:

0.000000 0.000000 0.000000
1.000000 1.000000 2.000000
2.000000 2.000000 4.000000
3.000000 3.000000 6.000000

x 的内存似乎被 y 覆盖,或者指向 y。如果我只有 xy(没有 z),那么一切都会按预期进行。

使用 double 而不是 float 表现出相同的行为。

关于我做错了什么有什么想法吗??谢谢!

保持数组存活,否则它们将被垃圾回收:

arrs = []
for i, k in enumerate(['x','y', 'z']):
    v = i*np.arange(n, dtype=np.float32)
    arrs.append(v)
    ...