Cython:访问 CPython 对象的私有 C 成员
Cython: Access to private C members of CPython object
在 http://docs.cython.org/src/userguide/extension_types.html#external-extension-types 中解释了如何访问 Python 扩展模块中对象的内部(隐藏或 "private")C 级成员。
我想从 sqlite3.Connection
对象访问内部成员 db
,该对象在 Python 的文件 Modules/_sqlite/connection.h
的结构 pysqlite_Connection
中定义2 来源。我是这样做的:
文件connection.pxd:
cdef extern from "connection.h":
struct sqlite3Connection:
sqlite3 *db
ctypedef class __builtin__.xConnection [object pysqlite_Connection]:
cdef sqlite3Connection conn
然后像这样使用它:
文件vtables.pxd:
from connection cimport xConnection
cdef dbname(xConnection c):
cdef sqlite3 *d
return sqlite3_db_filename(c.conn.db, "main")
这是用 cython 编译的,但是 当我 运行 C 编译器的结果时,我得到:
vtables.c:635:69: error: ‘pysqlite_Connection’ has no member named ‘conn’
__pyx_t_1 = __Pyx_PyBytes_FromString(sqlite3_db_filename(__pyx_v_c->conn.db, __pyx_k_main)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
^
生成的 C 代码似乎就像我正在访问 pysqlite_Connection
结构而不是包装 xConnection
,抱怨访问成员 conn
当然不是在 pysqlite_Connection
但在我的 xConnection
Cython class 中。但是在dbname
函数中参数明确定义为xConnection
。这似乎是 cython
编译器中的错误。还是我错过了什么?
我尝试按照文档中的方式提供 type
参数,例如:
ctypedef class __builtin__.xConnection [object pysqlite_Connection, type pysqlite_ConnectionType]:
cdef sqlite3Connection conn
但是 cython
崩溃了。
如果此方法 obsolete/not 不再受支持,是否还有其他选择?
我不认为你已经完成了你认为你已经完成的事情。您尚未创建名为 xConnection
的包装器 class。您已经向 Cython 保证已经有一个名为 __builtin__.xConnection
的 class 并且它是使用 C 结构 pysqlite_Connection
存储的,并且它包含一个 sqlite3Connection
结构,其中包含一个成员称为 db
.
我想你想告诉 Cython 的是,已经有一个名为 sqlite.Connection
的 class,它存储在 C 结构 pysqlite_Connection
中,其中包含一个名为 db
:
cdef extern from "connection.h":
# I assume you definite this somewhere else
ctypedef struct sqlite3:
pass
ctypedef class sqlite.Connection [object pysqlite_Connection]:
cdef sqlite3* db
cdef dbname(Connection c):
return sqlite3_db_filename(c.db, "main")
在 http://docs.cython.org/src/userguide/extension_types.html#external-extension-types 中解释了如何访问 Python 扩展模块中对象的内部(隐藏或 "private")C 级成员。
我想从 sqlite3.Connection
对象访问内部成员 db
,该对象在 Python 的文件 Modules/_sqlite/connection.h
的结构 pysqlite_Connection
中定义2 来源。我是这样做的:
文件connection.pxd:
cdef extern from "connection.h":
struct sqlite3Connection:
sqlite3 *db
ctypedef class __builtin__.xConnection [object pysqlite_Connection]:
cdef sqlite3Connection conn
然后像这样使用它:
文件vtables.pxd:
from connection cimport xConnection
cdef dbname(xConnection c):
cdef sqlite3 *d
return sqlite3_db_filename(c.conn.db, "main")
这是用 cython 编译的,但是 当我 运行 C 编译器的结果时,我得到:
vtables.c:635:69: error: ‘pysqlite_Connection’ has no member named ‘conn’
__pyx_t_1 = __Pyx_PyBytes_FromString(sqlite3_db_filename(__pyx_v_c->conn.db, __pyx_k_main)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
^
生成的 C 代码似乎就像我正在访问 pysqlite_Connection
结构而不是包装 xConnection
,抱怨访问成员 conn
当然不是在 pysqlite_Connection
但在我的 xConnection
Cython class 中。但是在dbname
函数中参数明确定义为xConnection
。这似乎是 cython
编译器中的错误。还是我错过了什么?
我尝试按照文档中的方式提供 type
参数,例如:
ctypedef class __builtin__.xConnection [object pysqlite_Connection, type pysqlite_ConnectionType]:
cdef sqlite3Connection conn
但是 cython
崩溃了。
如果此方法 obsolete/not 不再受支持,是否还有其他选择?
我不认为你已经完成了你认为你已经完成的事情。您尚未创建名为 xConnection
的包装器 class。您已经向 Cython 保证已经有一个名为 __builtin__.xConnection
的 class 并且它是使用 C 结构 pysqlite_Connection
存储的,并且它包含一个 sqlite3Connection
结构,其中包含一个成员称为 db
.
我想你想告诉 Cython 的是,已经有一个名为 sqlite.Connection
的 class,它存储在 C 结构 pysqlite_Connection
中,其中包含一个名为 db
:
cdef extern from "connection.h":
# I assume you definite this somewhere else
ctypedef struct sqlite3:
pass
ctypedef class sqlite.Connection [object pysqlite_Connection]:
cdef sqlite3* db
cdef dbname(Connection c):
return sqlite3_db_filename(c.db, "main")