gpt4 book ai didi

Python C API 读取列表列表,分配内存和全局变量

转载 作者:太空宇宙 更新时间:2023-11-04 03:47:04 24 4
gpt4 key购买 nike

我正在编写一个模块以优化操作,但我有几个问题。

首先

我需要从 python 到 C 读取一个数组(列表的列表),我已经这样做了:

long i_k;
for (int k = 0; k < n; k++) {
PyObject *first = PyList_GetItem(streamMatrixObj, k);
for (int i = 0; i < n; i++) {
PyObject *second = PyList_GetItem(first, i);
i_k = PyLong_AsLong(second);
f[k][i] = i_k;
}
}

矩阵总是n x n。有没有更好的方法来读取列表的列表并将其存储到 C 数组中?

第二

我像这样为 C 数组分配内存:

void **createMatrix(uint rows, uint cols) {

long **matrix;

const size_t row_pointers_bytes = rows * sizeof(*matrix);
const size_t row_elements_bytes = cols * sizeof(**matrix);
matrix = PyObject_Malloc(row_pointers_bytes + rows * row_elements_bytes);

if (!matrix) {
PyErr_NoMemory();
return NULL;
}

size_t i = 0;
long *data = matrix + rows;
for (i = 0; i < rows; i++)
matrix[i] = data + i * cols;

return matrix;
}

我应该使用 PyMem_Malloc 还是 PyObject_Malloc?,我在这个问题中看到了解释

Is there any reason to use malloc over PyMem_Malloc?

但仍然不知道调用什么函数比较合适。

第三

这个模块的方法会被调用很多次,所以,我想把C数组保存在内存中,以避免每次都重新创建数组。例如,从 python 中我会调用方法 myModule.deltaC(1,2,[1,2,3]) 并且该调用将对矩阵执行一些操作。

我能否在使用 deltaC 函数之前初始化数组,例如 myModule.initMatrix([[1,2,3],[1,2,3], [1,2 ,3]]) 并将其保存在内存中直到程序完成?那么 C 数组需要成为模块中的全局变量吗?

更新

我尝试使用 module.initMatrix 在全局变量中初始化 C 数组,但是当调用 module.delta 时,我在访问C 数组,所以我猜这是不可能的,或者我遗漏了一些东西。

第四个

有没有办法检测 python 程序何时完成,以便调用 PyObject_free(array) 释放为 C 数组分配的内存?

最佳答案

首先:这几乎就是应该如何完成的。

第二:据我了解,您应该在此处 PyMem_Malloc/PyMem_FreePyObject_Malloc/PyObject_Free 用于分配 Python 对象,并针对许多较小的对象进行了优化。但是,除非您分配大量内存或进行非常大量的分配,否则这无关紧要。

第三和第四:你可以使用 Capsules API 用于存储您的 C 结构并将它们传递给 API 函数。您可以让初始化函数 (initMatrix) 返回一个包含矩阵的胶囊并将该胶囊传递给其他函数(例如 deltaC),而不是存储全局矩阵。当矩阵不再被引用时,它会自动销毁。

如果您不打算存储除矩阵以外的任何内容,一个可能的替代方法是使用 numpy阵列。这些阵列可通过 numpy C API 直接访问从 C 作为矩阵。这将使您无需调用 Python C API 函数来检索矩阵的每个元素,自行分配内存或在销毁时释放内存。

关于Python C API 读取列表列表,分配内存和全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23442486/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com