小编Tom*_*ure的帖子

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

哦,我的话,我是个傻瓜. 在调用函数时,我只是省略了第二个和第三个参数.像一个傻瓜.因为那就是我.原来愚蠢的问题如下:

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

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

#include <stdio.h>

void cfun(const void * indatav, int rowcount, int colcount, void * outdatav) {
    //void cfun(const double * indata, int rowcount, int colcount, double * outdata) {
    const double * indata = (double *) indatav;
    double * outdata = (double *) outdatav;
    int i;
    puts("Here we go!");
    for (i = 0; i < rowcount * colcount; ++i) {
        outdata[i] = indata[i] * 2;
    }
    puts("Done!");
}
Run Code Online (Sandbox Code Playgroud)

(正如你可能猜到的那样,我最初的论点是double*而不是void*,但是无法弄清楚在Python方面该怎么做.我当然喜欢把它们改回来,但我并不挑剔只要它有效.)

我从中创建了一个共享库.gcc -fPIC …

python ctypes numpy ffi

50
推荐指数
2
解决办法
2万
查看次数

一个threading.Thread如何在Python中产生其余的量子?

我有一个线程正在轮询一块硬件.

while not hardware_is_ready():
    pass
process_data_from_hardware()
Run Code Online (Sandbox Code Playgroud)

但是还有其他线程(和进程!)可能有事情要做.如果是这样,我不想每次其他指令都烧掉cpu检查硬件.自从我处理线程以来已经有一段时间了,当我这样做时它不是Python,但我相信大多数线程库都有一个yield函数或某些东西允许线程告诉调度程序"给其他线程一个机会".

while not hardware_is_ready():
    threading.yield()          # This function doesn't exist.
process_data_from_hardware()
Run Code Online (Sandbox Code Playgroud)

但我在线程文档中找不到任何类似的引用.Python确实有一个yield声明,但我很确定这完全是另一回事(与生成器有关).

在这做什么是正确的?

python multithreading yield

41
推荐指数
3
解决办法
2万
查看次数

是否有关于Matlab内置函数可以抛出异常的权威参考?

例如,我想从imread()捕获一个无法读取的文件路径异常.我可以做这个.

imagePath = 'a_picture.jpg';
try
    im = imread(imagePath);
catch exception
    if strcmp(exception.identifier, 'MATLAB:imread:fileOpen')
        fprintf('Couldn''t open %s.\n', imagePath);
        im = [];
    else
        fprintf('Unexpected error (%s): %s\n', ...
                exception.identifier, exception.message);
        throw(exception);
    end
end
Run Code Online (Sandbox Code Playgroud)

但我知道发现与之比较的神奇字符串(在本例中为'MATLAB:imread:fileOpen')的唯一方法是:

  1. 导致错误,捕获异常,并查看标识符.但要做到这一点需要很长时间.例如,如果文件存在但实际上不是图像文件,Matlab是否使用不同的异常标识符?如果它存在但我没有读取权限怎么样?如果它是一个目录怎么办?

  2. 看一下源代码.imread()是用Matlab编写的,所以这是可能的,但它不适用于其他函数.当然,imread()调用其他不是用Matlab编写的函数,异常可能会从它们中冒出来.

有没有权威的方法让我知道imread()可以抛出的所有异常?我希望这是在文档的某个地方,但我找不到它.

matlab exception

12
推荐指数
1
解决办法
798
查看次数

我可以强迫一个numpy ndarray获取其内存的所有权吗?

我有一个C函数mallocs()并填充浮点数的二维数组.它"返回"该地址和数组的大小.签名是

int get_array_c(float** addr, int* nrows, int* ncols);
Run Code Online (Sandbox Code Playgroud)

我想用Python调用它,所以我使用ctypes.

import ctypes
mylib = ctypes.cdll.LoadLibrary('mylib.so')
get_array_c = mylib.get_array_c
Run Code Online (Sandbox Code Playgroud)

我从未弄清楚如何使用ctypes指定参数类型.我倾向于为我正在使用的每个C函数编写一个python包装器,并确保我在包装器中获得正确的类型.浮点数组是按主列顺序排列的矩阵,我想把它作为numpy.ndarray.但它非常大,所以我想使用C函数分配的内存,而不是复制它.(我刚刚在StackOverflow中找到了这个PyBuffer_FromMemory的答案:https://stackoverflow.com/a/4355701/3691 )

buffer_from_memory = ctypes.pythonapi.PyBuffer_FromMemory
buffer_from_memory.restype = ctypes.py_object

import numpy
def get_array_py():
    nrows = ctypes.c_int()
    ncols = ctypes.c_int()
    addr_ptr = ctypes.POINTER(ctypes.c_float)()
    get_array_c(ctypes.byref(addr_ptr), ctypes.byref(nrows), ctypes.byref(ncols))
    buf = buffer_from_memory(addr_ptr, 4 * nrows * ncols)
    return numpy.ndarray((nrows, ncols), dtype=numpy.float32, order='F',
                         buffer=buf)
Run Code Online (Sandbox Code Playgroud)

这似乎给了我一个具有正确值的数组.但我很确定这是一个内存泄漏.

>>> a = get_array_py()
>>> a.flags.owndata
False
Run Code Online (Sandbox Code Playgroud)

该阵列不拥有内存.很公平; 默认情况下,当从缓冲区创建数组时,它不应该.但在这种情况下它应该.删除numpy数组时,我真的很想让python为我释放缓冲区内存.似乎我可以强制将owndata强制为True,那应该这样做,但是owndata是不可设置的.

不满意的解决方案:

  1. 让get_array_py()的调用者负责释放内存.这太烦人了; 调用者应该能够像任何其他numpy数组一样处理这个numpy数组.

  2. 将原始数组复制到get_array_py中的新numpy数组(具有自己的独立内存),删除第一个数组,并释放get_array_py()中的内存.返回副本而不是原始数组.这很烦人,因为它应该是不必要的内存副本.

有办法做我想要的吗?我不能修改C函数本身,虽然我可以在库中添加另一个C函数,如果这有用的话.

c python free ctypes numpy

11
推荐指数
2
解决办法
2082
查看次数

标签 统计

python ×3

ctypes ×2

numpy ×2

c ×1

exception ×1

ffi ×1

free ×1

matlab ×1

multithreading ×1

yield ×1