Я пишу оболочку Cython для библиотеки NAG C.
В одном из файлов заголовков библиотеки NAG C есть макросы:
#define NAG_FREE(x) x04bdc((Pointer *)&(x))
Указатель is void *
x04bd c is:
extern void NAG_CALL x04bdc(Pointer *ptr);
NAG_FREE - это эквивалент библиотеки NAG функции free () для освобождения памяти.
Вот отрывок из моего файла lib_nag_integrate.pxd:
cdef extern from "<nagx04.h>":
void x04bdc(Pointer *ptr)
x04bd c - это «модная» бесплатная (mallo c) процедура. Я не могу получить доступ к этому коду.
Затем я создаю функцию cdef в моем файле .pyx:
cdef void NAG_FREE(double *x):
x04bdc(<Pointer *>&x)
Здесь я ввел тип, приведенный x к двойному указателю, так как это то, что я пытается освободить память, однако примеры библиотеки NAG, похоже, используют ее для любого типа указателя.
При запуске сценария python, который вызывает функцию cpdef, которая в конечном итоге использует NAG_FREE, я получаю следующую ошибку:
Process finished with exit code 134 (interrupted by signal 6: SIGABRT)
Если я закомментирую вызовы NAG_FREE, он работает нормально, однако NAG говорит, что необходимо использовать NAG_FREE.
Функция cdef, использующая NAG_FREE:
cdef (double,double,Integer,Integer) dim1_fin_gen(lib_nag_integrate.NAG_D01SJC_FUN objfun,double a, double b,double epsabs, double epsrel,
Integer max_num_subint,Nag_User *comm,integration_out *output):
"""
:param f: user function
:type f: function
:param a: lower limit of integration
:type a: real float
:param b: upper limit of integration
:type b: real float
:param epsabs: user requested absolute error
:type epsabs: integer
:param epsrel: user requested relative error
:type epsrel: integer
:param max_num_subint: maximum number of subintervals
:type max_num_subint: real integer
:return: integration value of user function f
:rtype: real float
"""
cdef lib_nag_integrate.Nag_QuadProgress _qp
cdef lib_nag_integrate.NagError _fail
cdef double result
cdef double abserr
_fail.print = True
_fail.code = 0
_fail.errnum = 0
_fail.handler = NULL
lib_nag_integrate.d01sjc(objfun, a, b, epsabs, epsrel,
max_num_subint, &result, &abserr,
&_qp, comm, &_fail)
if _fail.code > 0 :
errorMessage = _fail.message
raise NagException(_fail.code,errorMessage)
print(_fail.message)
else:
output[0].result = result
output[0].abserr = abserr
output[0].fun_count = _qp.fun_count
output[0].num_subint = _qp.num_subint
NAG_FREE(_qp.sub_int_beg_pts)
NAG_FREE(_qp.sub_int_end_pts)
NAG_FREE(_qp.sub_int_result)
NAG_FREE(_qp.sub_int_error)
Мой заголовочный файл libnag_integrate.pxd импортирует из библиотеки c следующее:
cdef extern from "<nag_types.h>":
ctypedef bint Nag_Boolean
ctypedef long Integer
ctypedef void* Pointer
ctypedef struct NagError:
int code
bint print "print"
char message[512]
Integer errnum
void (*handler)(char*,int,char*)
ctypedef struct Nag_User:
Pointer p
ctypedef struct Nag_QuadProgress:
Integer num_subint
Integer fun_count
double *sub_int_beg_pts
double *sub_int_end_pts
double *sub_int_result
double *sub_int_error
cdef extern from "<nagx04.h>":
(void*) NAG_ALLOC "x04bjc" (size_t size)
void x04bdc(Pointer *ptr)
cdef extern from "<nagd01.h>":
void d01sjc(NAG_D01SJC_FUN f, double a, double b,
double epsabs, double epsrel, Integer max_num_subint, double *result,
double *abserr, Nag_QuadProgress *qp, Nag_User *comm,
NagError *fail)
d01sj c - это процедура интеграции, к которой я не могу получить доступ. Он выделяет память qp.sub_int_beg_pts et c внутри.
Я думаю, что у меня поврежденный указатель, вызывающий ошибку. Если да, то где это и как исправить?
большое спасибо
При дальнейшем осмотре структуры _qp. Та же ошибка возникает при разыменовании, например:
x = _qp.sub_int_end_pts[0]
, поэтому разыменование _qp вызывает ошибку.
Тип структуры Nag_QuadProgress импортируется из файла заголовка NAG в мой .pxd следующим образом:
cdef extern from "<nag_types.h>":
ctypedef struct Nag_QuadProgress:
Integer num_subint
Integer fun_count
double *sub_int_beg_pts
double *sub_int_end_pts
double *sub_int_result
double *sub_int_error
Есть идеи, почему разыменование указателей в этой структуре вызывает ошибку?