[英]Wrapping C header macros with Cython
我正在為 NAG C 庫編寫 Cython 包裝器。
在 NAG C 庫中的 header 文件之一是宏:
#define NAG_FREE(x) x04bdc((Pointer *)&(x))
指針無效*
x04bdc 是:
extern void NAG_CALL x04bdc(Pointer *ptr);
NAG_FREE 是相當於 free() 的 NAG 庫,用於釋放 memory。
這是我的 lib_nag_integrate.pxd 文件的摘錄:
cdef extern from "<nagx04.h>":
void x04bdc(Pointer *ptr)
x04bdc 是一個“花哨的”免費 (malloc) 例程。 我無法訪問此代碼。
然后我在 my.pyx 文件中創建一個 cdef function :
cdef void NAG_FREE(double *x):
x04bdc(<Pointer *>&x)
在這里,我將 x 類型轉換為雙指針,因為這是我試圖從 memory 中釋放出來的,但是 NAG 庫示例似乎將它用於任何類型的指針。
當運行 python 腳本調用最終使用 NAG_FREE 的 cpdef function 時,我收到以下錯誤:
Process finished with exit code 134 (interrupted by signal 6: SIGABRT)
如果我注釋掉 NAG_FREE 調用,那么它工作正常,但是 NAG 說有必要使用 NAG_FREE。
使用 NAG_FREE 的 cdef function 是:
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 header 文件從 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)
d01sjc 是我無法訪問的集成例程。 它在里面分配qp.sub_int_beg_pts等的memory。
我想我有一個損壞的指針導致錯誤。 如果是這樣,它在哪里以及如何修復它?
非常感謝
進一步檢查結構“_qp”。 取消引用時會發生相同的錯誤,例如:
x = _qp.sub_int_end_pts[0]
所以它是導致錯誤的 _qp 的取消引用。
結構類型 Nag_QuadProgress 從其 NAG header 文件導入到 my.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
任何想法為什么取消引用此結構中的指針會導致錯誤?
從 Cython 的角度來看,您將NAG_FREE
用作 function,因此您應該將其聲明為。 它是一個真正的宏並不重要,嘗試重新實現它當然也無濟於事。
cdef extern from "whatever_the_nag_header_is":
void NAG_FREE(Pointer x)
# or
void NAG_FREE(void *x)
# or
void NAG_FREE(...) # accepts anything - Cython doesn't attempt to match types
您可能需要嘗試使用 arguments 的類型才能使其工作 - 我建議了三個選項。
實際上,您要做的就是為 Cython 提供足夠的信息,使其可以生成正確的 C 代碼,而正確的 C 代碼是NAG_FREE(your_variable)
,就好像它是 ZC1C425268E17A98 調用一樣。
使用您的代碼:
(<integration_out*>output)[0]
表明你做錯了什么。 output
是一個integration_out
指針,那么你為什么要轉換它呢? 它要么什么都不做,要么引入一個潛在的錯誤。
盡管聲稱返回 C 元組類型,但您實際上並不費心返回任何東西。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.