【问题标题】:Cython: Access to private C members of CPython objectCython:访问 CPython 对象的私有 C 成员
【发布时间】:2016-01-10 06:40:26
【问题描述】:

http://docs.cython.org/src/userguide/extension_types.html#external-extension-types 解释了如何访问 Python 扩展模块中对象的内部(隐藏或“私有”)C 级成员。

我想从sqlite3.Connection 对象访问内部成员db,该对象在Python2 源文件Modules/_sqlite/connection.h 的结构pysqlite_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 中,而是在我的 @ 987654333@ Cython 班。但在dbname 函数中,参数明确定义为xConnection。这似乎是cython 编译器中的一个错误。还是我错过了什么?

我尝试在文档中提供type 参数,例如:

ctypedef class __builtin__.xConnection [object pysqlite_Connection, type pysqlite_ConnectionType]:
    cdef sqlite3Connection conn

但随后cython 崩溃了。

如果此方法已过时/不再受支持,是否有替代方法?

【问题讨论】:

    标签: python c types cython


    【解决方案1】:

    我不认为你已经完成了你认为你已经完成的事情。您尚未创建名为xConnection 的包装类。您已经向 Cython 保证,已经有一个名为 __builtin__.xConnection 的类,它使用 C 结构 pysqlite_Connection 存储,它包含一个 sqlite3Connection 结构,其中包含一个名为 db 的成员。

    我想你想告诉 Cython 已经有一个名为 sqlite.Connection 的类,它存储在 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")
    

    【讨论】:

    • 似乎有效。除了调用sqlite3_db_filename 在准备调用时崩溃。我可能不得不为此提出一个新问题。
    • 现在工作。 sqlite_db_filename 的返回类型必须正确定义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-30
    • 1970-01-01
    • 2012-02-18
    • 2013-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多