我目前有点陷入困境,希望得到一些指导。我有一个包装sqlite的小模块,我想允许使用sqlite提供的钩子来执行用户定义的Python函数。
以下是SQLite头文件中的定义:
SELECT TOP (sites.Credits) pages.Id, sites.Id
FROM sites s CROSS APPLY
(SELECT p.*, row_number() over (order by (select null)) as seqnum
FROM pages p
WHERE p.Id = p.WebSites_Id
) p
where seqnum <= s.credits;
这是相应的Cython:
cdef extern from "sqlite3.h":
cdef void *sqlite3_commit_hook(sqlite3*, int(*xFunc)(void*), void*)
使用gdb,这里是回溯:
# Reference to user-provided function.
cdef object py_commit_hook = None
# Typedef for callback
ctypedef int(*commit_callback)(void *data)
# Wrapper function that will in turn call the user-provided python callback.
cdef int commit_hook_wrapper(void *data):
print 'hello' # Just for debugging.
py_commit_hook()
# API used to set callback and make sqlite3 library call.
def set_commit_hook(DatabaseHelper db, callback):
cdef commit_callback f
global py_commit_hook
py_commit_hook = callback
f = commit_hook_wrapper
sqlite3_commit_hook(db.db, f, <void *>0)
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7b16e2d in PySys_GetObject () from /usr/lib/libpython2.7.so.1.0
(gdb) bt
#0 0x00007ffff7b16e2d in PySys_GetObject () from /usr/lib/libpython2.7.so.1.0
#1 0x00007ffff567d291 in __Pyx_GetStdout () at pysqlite_ext.c:6121
#2 __Pyx_PrintOne (f=0x0, o=0x7ffff7e39270) at pysqlite_ext.c:6227
#3 __pyx_f_12pysqlite_ext_commit_hook_wrapper (__pyx_v_data=<optimized out>)
at pysqlite_ext.c:2526
#4 0x00007ffff58ffb36 in ?? () from /usr/lib/libsqlite3.so.0
#5 0x00007ffff590ac5e in ?? () from /usr/lib/libsqlite3.so.0
#6 0x00007ffff590bd4f in sqlite3_step () from /usr/lib/libsqlite3.so.0
#7 0x00007ffff5b6ffb0 in pysqlite_step ()
from /usr/lib/python2.7/lib-dynload/_sqlite3.so
函数print
调用似乎失败了:
commit_hook_wrapper
我完全难过!什么想法可能会出错?
我动态链接到libsqlite3,我想知道这可能是问题。我之前已经在这些方面实施了回调,并且从未遇到过问题,但是这次无论我尝试什么,它似乎都会失败。
答案 0 :(得分:4)
在cython-users列表中,有人建议我使用gil&#34;将我的回调声明为&#34;。修正了它:
cdef int commit_hook_wrapper(void *data) with gil:
print 'hello'
py_commit_hook()
答案 1 :(得分:0)
有关您的问题的一些信息可以在这里找到: (对不起,我还不能发表评论) http://docs.cython.org/en/latest/src/userguide/external_C_code.html#acquiring-and-releasing-the-gil
要在没有GIL的情况下执行的C代码回调的C函数需要先获取GIL才能操作Python对象。