Tôi đang sử dụng API C có nhiều chức năng để viết một số hàm để tính toán ma trận. Hôm nay tôi muốn di chuyển một số phần của hàm vào một tệp .c riêng biệt và sử dụng tiêu đề để khai báo chúng. Bây giờ tôi có một vấn đề lạ mà phải làm với chức năng import_array
của numpy. Tôi đã cố gắng đơn giản hóa vấn đề càng nhiều càng tốt. Lúc đầu có chương trình công tác:API Numpy C: Liên kết một số tệp đối tượng
mytest.c
#include "mytest.h"
PyObject* my_sub_function() {
npy_intp dims[2] = {2, 2};
double data[] = {0.1, 0.2, 0.3, 0.4};
PyArrayObject* matrix = (PyArrayObject*)PyArray_SimpleNew(2, dims, NPY_FLOAT64);
memcpy(PyArray_DATA(matrix), data, sizeof(double) * dims[0] * dims[1]);
return (PyObject*)matrix;
}
static PyObject* my_test_function(PyObject* self, PyObject* args) {
return my_sub_function();
}
static PyMethodDef methods[] = {
{"my_test_function", my_test_function, METH_VARARGS, ""},
{0, 0, 0, 0}
};
static struct PyModuleDef module = {
PyModuleDef_HEAD_INIT, "mytest", 0, -1, methods
};
PyMODINIT_FUNC PyInit_mytest() {
import_array();
return PyModule_Create(&module);
}
mytest.h
#ifndef mytest_h
#define mytest_h
#include <Python.h>
#include <numpy/arrayobject.h>
#include <numpy/npy_common.h>
PyObject* my_sub_function();
#endif
Makefile
all: mytest.o sub.o
gcc -shared -Wl,-soname,mytest.so -o mytest.so mytest.o
mytest.o: sub.o
gcc -fPIC -c mytest.c `pkg-config --cflags python3`
clean:
rm -rf *.so
rm -rf *.o
Mọi thứ hoạt động như mong đợi. Tôi có thể gọi make
và sau đó tải các module và gọi hàm:
test.py
import mytest
print(mytest.my_test_function())
Nếu tôi sẽ loại bỏ import_array
từ hàm init sẽ có một segfault, đó là hành vi mà đã được báo cáo trong nhiều danh sách gửi thư và diễn đàn.
Bây giờ tôi chỉ muốn loại bỏ toàn bộ chức năng my_sub_function
từ mytest.c và di chuyển nó vào một tập tin gọi sub.c:
#include "mytest.h"
PyObject* my_sub_function() {
npy_intp dims[2] = {2, 2};
double data[] = {0.1, 0.2, 0.3, 0.4};
PyArrayObject* matrix = (PyArrayObject*)PyArray_SimpleNew(2, dims, NPY_FLOAT64);
memcpy(PyArray_DATA(matrix), data, sizeof(double) * dims[0] * dims[1]);
return (PyObject*)matrix;
}
mới Makefile là:
all: mytest.o sub.o
gcc -shared -Wl,-soname,mytest.so -o mytest.so mytest.o sub.o
mytest.o:
gcc -fPIC -c mytest.c `pkg-config --cflags python3`
sub.o:
gcc -fPIC -c sub.c `pkg-config --cflags python3`
clean:
rm -rf *.so
rm -rf *.o
Nếu tôi cố tải mô-đun và gọi hàm ngay bây giờ, cuộc gọi hàm sẽ cho tôi một khoảng cách. Tôi có thể giải quyết vấn đề nếu tôi đặt một cuộc gọi đến import_array
lên đầu my_sub_function
, nhưng tôi không nghĩ rằng đây là cách mà chức năng nên được sử dụng.
Vì vậy, tôi muốn biết lý do tại sao điều này đang xảy ra và cách "sạch" để chia nhỏ mô-đun numpy thành nhiều tệp nguồn.