简体   繁体   English

Cython:访问CPython对象的私有C成员

[英]Cython: Access to private C members of CPython object

In http://docs.cython.org/src/userguide/extension_types.html#external-extension-types it's explained how to access internal (hidden or "private") C-level members of objects in a Python extension module. http://docs.cython.org/src/userguide/extension_types.html#external-extension-types中 ,说明了如何访问Python扩展模块中对象的内部(隐藏或“私有”)C级成员。

I want to access the internal member db from a sqlite3.Connection object which is defined in a struct pysqlite_Connection in file Modules/_sqlite/connection.h of the Python2 source. 我想从sqlite3.Connection对象访问内部成员db ,该对象在Python2源文件的Modules/_sqlite/connection.h中的结构pysqlite_Connection中定义。 I do it like this: 我这样做是这样的:

File connection.pxd: 文件connection.pxd:

cdef extern from "connection.h":
    struct sqlite3Connection:
        sqlite3 *db

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

and then use it like this: 然后像这样使用它:

File vtables.pxd: 文件vtables.pxd:

from connection cimport xConnection

cdef dbname(xConnection c):
    cdef sqlite3 *d
    return sqlite3_db_filename(c.conn.db, "main")

This compiles with cython, but when I run the C compiler on the result, I get: 这可以使用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;}
                                                                     ^

The generated C code seems to act as if I was accessing the pysqlite_Connection struct instead of the wrapping xConnection , complaining about access to a member conn which is of course not in pysqlite_Connection but in my xConnection Cython class. 生成的C代码似乎就像我在访问pysqlite_Connection结构而不是包装xConnection ,抱怨访问成员conn ,而该成员conn当然不在pysqlite_Connection而是在我的xConnection Cython类中。 But in the dbname function the parameter is clearly defined as xConnection . 但是在dbname函数中,该参数明确定义为xConnection This seems like a bug in the cython compiler. 这似乎是cython编译器中的错误。 Or did I miss something? 还是我错过了什么?

I tried to give the type parameter as in the documentation, like: 我试图提供文档中的type参数,例如:

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

but then cython crashed. 但随后cython崩溃了。

If this method is obsolete/not supported anymore, are there any alternatives? 如果此方法已过时/不再受支持,是否有其他选择?

I don't think you've quite done what you think you've done. 我认为您尚未完成自己认为已完成的工作。 You haven't created a wrapper class called xConnection . 您尚未创建一个名为xConnection的包装器类。 You've assured Cython that there is already a class called __builtin__.xConnection and that it is stored using the C structure pysqlite_Connection , and it contains a sqlite3Connection struct which contains a member called db . 您已经向Cython保证,已经有一个名为__builtin__.xConnection的类,并且使用C结构pysqlite_Connection存储,并且它包含一个sqlite3Connection结构,该结构包含一个名为db的成员。

I think what you want to tell Cython that there is already a class called sqlite.Connection , that is stored in the C structure pysqlite_Connection and which contains a member called 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")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM