Использование SWIG требует карты типов для всей структуры.Типовых карт только для членов-указателей недостаточно, поскольку у них нет контекста, чтобы узнать, с каким размером инициализировать массивы NumPy.Мне удалось получить то, что я хотел, с помощью следующих наборов карт (которые были в основном скопированы и вставлены из numpy.i и адаптированы к моим потребностям, вероятно, не очень надежные):
%typemap (in,numinputs=0) element * (element temp) {
$1 = &temp;
}
%typemap (argout) element * {
/* weight */
{
npy_intp dims[1] = { $1->ngi };
PyObject * array = PyArray_SimpleNewFromData(1, dims, NPY_DOUBLE, (void*)($1->weight));
if (!array) SWIG_fail;
$result = SWIG_Python_AppendOutput($result,array);
}
/* l */
{
npy_intp dims[2] = { $1->ngi, $1->dim };
PyObject * array = PyArray_SimpleNewFromData(2, dims, NPY_DOUBLE, (void*)($1->l));
if (!array) SWIG_fail;
$result = SWIG_Python_AppendOutput($result,array);
}
/* n */
{
npy_intp dims[2] = { $1->ngi, $1->vertices };
PyObject * array = PyArray_SimpleNewFromData(2, dims, NPY_DOUBLE, (void*)($1->n));
if (!array) SWIG_fail;
$result = SWIG_Python_AppendOutput($result,array);
}
/* dn */
{
npy_intp dims[3] = { $1->ngi, $1->vertices, $1->dim };
PyObject * array = PyArray_SimpleNewFromData(3, dims, NPY_DOUBLE, (void*)($1->dn));
if (!array) SWIG_fail;
$result = SWIG_Python_AppendOutput($result,array);
}
}
Это работает в отличие от функции Cтем, что он возвращает кортеж массивов NumPy с нужными мне данными, что более удобно, чем необходимость извлекать их из объекта element
позже.Кроме того, первая карта типов устраняет необходимость передавать объект типа element
.Следовательно, я могу полностью скрыть структуру element
от пользователя python.
Интерфейс python, наконец, выглядит следующим образом:
weight, l, n, dn = get_element(dim, vertices, quadrature_degree, polynomial_degree)