指定类型#

包含代码片段#

可能存在重复的XML代码,例如需要在非类型继承关系相关的类上做的函数修改。可以将这些代码片段拆分出来,并通过实体引用包含它们。

<typesystem>
    <object-type name="A">
        &common_function_modifications;
    </object-type>
    <object-type name="B">
        &common_function_modifications;
    </object-type>
</typesystem>

实体名称被解释为文件名(后缀 xml)并解析在类型系统路径中作为命令行参数传递。

注意,这不是一个标准的对外部解析的实体,因为底层解析器的限制。

typesystem#

这是包含所有类型系统信息的根节点。它可能包含 添加函数容器类型自定义类型枚举类型额外包含函数加载类型系统命名空间对象类型透明容器原始类型拒绝智能指针类型抑制警告模板系统包含类型定义值类型子节点。

它可以有多个属性,以下将描述。

<typesystem package="..." submodule-of="..." allow-thread="..."
            exception-handling="..." snake-case="yes | no | both" >
</typesystem>

package 属性是一个字符串,描述要使用的包,例如 “QtCore”。

可选的 submodule-of 属性指定将模块作为子模块添加到的模块的名称。这需要相应地调整模块的安装目录。

可选的 属性 allow-threadexception-handing 指定函数修改的默认处理方式(见修改函数)。

可选的 snake-case 属性指定是否将函数和字段名自动更改为 Python 中常见的蛇形命名风格(例如,snakeCase 将更改为 snake_case)。

both 表示函数或字段将在其原始名称和蛇形版本下公开。不过,这也有限制。

  • 当在 Python 中重写 C++ 类的虚函数时,必须使用蛇形名称。

  • 当类成员函数的静态和非静态重载存在(例如,对于 QFileInfo::exists()),必须使用蛇形名称。

load-typesystem#

load-typesystem 节点指定在将多个库映射到其他语言或将一个库基于另一个库时加载哪些类型系统,并且它是 typesystem 节点的子节点。

<typesystem>
    <load-typesystem name="..." generate="yes | no" />
</typesystem>

名称属性是要加载的类型系统的文件名,generate 属性指定是否生成代码。当基于一个库生成其他库时,必须指定后者,使得生成器能够理解继承层次、原语映射、函数中的参数类型等。

大多数库都将基于 QtCore 和 QtGui 模块,在这种情况下,这些库的代码生成将被禁用。

rejection#

rejection 节点拒绝给定的类,或指定的函数或字段,它是 typesystem 节点的子节点。

<typesystem>
    <rejection class="..."
        function-name="..."
        argument-type="..."
        field-name="..." />
</typesystem>

class 属性是要拒绝的 C++ 类的名称。使用可选的 function-nameargument-typefield-name 属性拒绝特定的函数、具有特定类型参数的函数或字段。注意,不能同时指定 field-namefunction-name/argument-type。为了移除给定字段或函数的所有出现,将类属性设置为 *。

primitive-type#

primitive-type 节点描述了如何将基础类型从 C++ 映射到目标语言,并且它是 typesystem 节点的子节点。它可以包含 conversion-rule 子节点。请注意,大多数原语已在 QtCore 类型系统中指定(参见 Primitive C++ Types)。

<typesystem>
    <primitive-type name="..."
        since="..."
        until="..."
        target-lang-api-name="..."
        default-constructor="..."
        preferred-conversion="yes | no" />
        view-on="..."
</typesystem>

name 属性是 C++ 中原语的名称。

可选的 target-lang-api-name 属性是目标语言中原始类型名称,默认为 name 属性。

可选的 since 值用于指定类型首次引入的 API 版本。

类似地,可选的 until 值可以用于指定类型将在哪个 API 版本中被弃用。

如果设置可选的 preferred-conversion属性为no,则表示这种原始类型的版本不是目标语言类型的首选C++等价类型。例如,在Python中,“qint64”和“long long”都变为“long”,但我们应该首选“qint64”版本。因此,我们用preferred-conversion="no"标记“long long”。

可选的 default-constructor指定了构建原始类型的单个值所需的最小子构造函数调用。当原始类型可以使用默认构造函数(没有参数的构造函数)构建时,这不必要。

可选的 preferred-conversion属性说明如何构建原始类型的默认实例。它应该是一个能够创建原始类型实例的构造函数调用。例如,一个名为“Foo”的类可以将preferred-conversion值设置为“Foo()”。通常,该属性仅用于声明为原始类型的类,而不是原始的C++类型,但这取决于使用ApiExtractor的应用。

可选的 view-on属性指定了该类型是一个视图类,如std::string_view或QStringView,它接受另一个类型(如std::string或QString)作为构造函数参数。由于通常不能向视图类赋值,因此不能为他们生成目标到本地类型的转换。相反,应该实例化被观察的类,并将实例传递给使用视图类作为参数类型的函数。

有关内置模板的规范类型转换规则,请参阅预定义模板

namespace-type#

namespace-type节点将指定的C++命名空间映射到目标语言,并且它是类型系统节点或其他namespace-type节点的子节点。它可以包含add-functiondeclare-functionenum-typeextra-includesincludemodify-functionnamespace-typeobject-typesmart-pointer-typetypedef-typevalue-type子节点。

<typesystem>
    <namespace-type name="..."
        visible="true | auto | false"
        generate="yes | no"
        generate-using="yes | no"
        package="..."
        since="..."
        extends = "..."
        files = "..."
        revision="..." />
</typesystem>

name属性是命名空间的名字,例如,“Qt”。

可选的 visible属性用来指定命名空间是否可以在目标语言名称中可见。其默认值是auto。这意味着常规命名空间是可见的,但内联命名空间(在C++ 11中引入)将不可见。

内联命名空间的检测需要使用LLVM 9.0构建shiboken。

可选的 generate是一个过时的属性。指定no等同于visible="false"

可选的 generate-using 属性指定是否将 using namespace 生成到命名空间内的类包装代码中(默认:是)。这确保例如默认参数值的完全限定的枚举值可以编译。然而,在罕见的情况下,它可能会引起歧义,此时可以关闭它。

可以使用 package 属性来覆盖类型系统的包。

可选的 since 值用于指定此类型的 API 版本。

revision 属性可用于为每个类型指定修订版,以简化生成与 ABI 兼容的绑定。

可选的 extends 属性在跨多个模块的命名空间中指定给定命名空间首次出现的位置的模块名称。例如,在 Qt 中,命名空间 Qt 首次出现在 QtCore 模块中,并在 QtGui 模块中进一步填充。如果指定了 extends,则将生成 QtGui.Qt,它扩展 QtCore.Qt

可选的 file 属性在跨多个模块的命名空间中指定正则表达式以匹配相关联的包含文件的内容,这些文件与当前模块相关。

枚举类型#

enum-type 节点将给定的枚举从 C++ 映射到目标语言,并且它是 typesystem 节点的子节点。使用 reject-enum-value 子节点来拒绝值。

<typesystem>
    <enum-type name="..."
        identified-by-value="..."
        class="yes | no"
        since="..."
        flags="yes | no"
        flags-revision="..."
        cpp-type = "..."
        doc-file = "..."
        python-type = "IntEnum | IntFlag"
        lower-bound="..."
        upper-bound="..."
        force-integer="yes | no"
        extensible="yes | no"
        revision="..." />
</typesystem>

name 属性是枚举的完全限定的 C++ 名称(例如,“Qt::FillRule”)。如果设置 可选的 flags 属性为 yes(默认为 no),则生成器将期望给定枚举类型的现有 QFlags<T>。使用 lower-boundupper-bound 属性来指定枚举值的运行时边界检查。值必须是一个可编译的目标语言语句,例如 “QGradient.Spread.PadSpread”(再以 Python 为例)。如果将 force-integer 属性设置为 yes(默认为 no),则生成的目标语言代码将使用目标语言整数而不是枚举。最后,extensible 属性指定给定的枚举是否可以通过用户值进行扩展(默认为 no)。

可选的 since 值用于指定此类型的 API 版本。

identified-by-value 属性有助于使用其中一个值的名称来指定匿名枚举,这个值对于匿名枚举范围是唯一的。注意,enum-type 标签可以或有一个 name 或一个 identified-by-value,但不能同时存在。

可选的 python-type 属性指定底层 Python 类型。

可选的 cpp-type 属性指定用于转换值的 C++。对于触发 MSVC 有符号性问题的较大值,这可能很有用。

可选的 doc-file 属性指定 C++ 或 .qdoc 文件的基名称,该文件由 \relates\headerfile 指示,SDK 中的文档将添加并显示,如果有全局枚举。此属性只为 qdoc

revision 属性可用于为每个类型指定修订版,以简化生成与 ABI 兼容的绑定。

flags-revision 属性与 revision 属性有相同的用途,但用于与枚举相关联的 QFlag。

拒绝枚举值#

reject-enum-value 节点拒绝由 name 属性指定的枚举值,它是 enum-type 节点的子节点。

<enum-type>
    <reject-enum-value name="..."/>
</enum-type>

当 C++ 枚举实现有几个相同的数值时,这个节点就被使用,其中一些通常是过时的。

value-type#

value-type 节点表示给定的 C++ 类型作为值类型映射到目标语言中。这意味着在 C++ 中它是一个按值传递的对象,即它存储在函数调用栈中。它是 typesystem 节点或其他类型节点的子节点,可能包含 add-functionadd-pymethoddefconfigurationdeclare-functionconversion-ruleenum-typeextra-includesincludemodify-functionobject-typesmart-pointer-typetypedef-type 或进一步的 value-type 子节点。

<typesystem>
    <value-type name="..." since="..."
     copyable="yes | no"
     allow-thread="..."
     disable-wrapper="yes | no"
     exception-handling="..."
     generate-functions="..."
     isNull ="yes | no"
     operator-bool="yes | no"
     hash-function="..."
     private="yes | no"
     qt-register-metatype = "yes | no | base"
     stream="yes | no"
     default-constructor="..."
     revision="..."
     snake-case="yes | no | both" />
</typesystem>

name 属性是完全限定的 C++ 类名,例如 “QMatrix” 或 “QPainterPath::Element”。copyable 属性用于强制或省略此类型是否可复制。可选的 hash-function 属性通知函数名称的哈希函数。

可选的 stream 属性指定此类型是否能够使用外部定义的运算符,如 QDataStream << 和 >>。如果等于 yes,这些运算符将作为当前类中的普通方法调用。

可选的 since 值用于指定此类型的 API 版本。

可选的 default-constructor 指定构建一个值类型实例所需的最小构造函数调用。如果值类型可以使用默认构造函数(不带参数)构建,则不需要它。通常,代码生成器可以基于构造函数签名猜测值类型的最小构造函数,因此仅在非常特殊的情况下使用 default-constructor

关于可选的 disable-wrappergenerate-functions 属性,请参阅 object-type

关于可选的 private 属性,请参阅 Defining Entities

可选的 qt-register-metatype 属性确定是否为 name 生成 Qt 元类型注册。默认情况下,非抽象的可默认构造的类型会被生成以在信号和槽中使用。值 base 表示除了派生类外,还会为问题中的类生成注册。这允许将注册限制为类型层次结构的基类。

revision 属性可用于为每个类型指定修订版,以简化生成与 ABI 兼容的绑定。

可选的 属性 allow-threadexception-handing 指定函数修改的默认处理方式(见修改函数)。

可选的 snake-case 属性允许覆盖 typesystem 元素上指定的值。

可选的 isNulloperator-bool 属性可以用来覆盖生成布尔转换的命令行设置(请参阅 Bool Cast)。

object-type#

object-type节点指示给定的C++类型被映射为目标语言的对象类型。这意味着它在C++中以指针传输对象,并在堆上存储。它是typesystem节点或其他类型节点的子节点,并可能包含add-function、add-pymethoddef、configuration、declare-function、enum-type、extra-includes、include、modify-function、object-type、smart-pointer-type、typedef-type或value-type子节点。

<typesystem>
    <object-type name="..."
     since="..."
     copyable="yes | no"
     allow-thread="..."
     disable-wrapper="yes | no"
     exception-handling="..."
     generate-functions="..."
     force-abstract="yes | no"
     hash-function="..."
     isNull ="yes | no"
     operator-bool="yes | no"
     parent-management="yes | no"
     polymorphic-id-expression="..."
     polymorphic-name-function="..."
     private="yes | no"
     qt-metaobject="yes | no"
     qt-register-metatype = "yes | no | base"
     stream="yes | no"
     revision="..."
     snake-case="yes | no | both" />
</typesystem>

name属性是完整的C++类名。如果没有C++基类,可以使用default-superclass属性在生成的目标语言API中指定给定类型的超类。copyable和hash-function属性与value-type中描述的相同。

可选的force-abstract属性强制类为抽象类,禁用其实例化。如果类继承自类型系统中的非抽象基类,则生成器通常会自动检测此属性。

可选的disable-wrapper属性禁用生成C++ Wrapper(见代码生成术语)。这将有效地禁用Python中类的虚拟方法重写。在类不能从Python实例化且其虚拟方法对代码生成器(通过返回引用或使用无法生成的参数默认值等)造成问题时,可以使用此功能。

关于可选的 private 属性,请参阅 Defining Entities

可选的qt-metaobject属性指定是否生成特殊的Qt虚拟函数metaObject()、metaCall()和metaCast()。对于使用动态元对象的类,例如QDBusInterface,可以关闭此功能。

可选的qt-register-metatype属性确定是否为name *生成Qt元类型注册。默认情况下,只有在非QObject类型中用于信号和槽时才生成注册。值base表示将为此类生成注册,而不是继承自类的注册。这允许限制注册到类型层次结构的基础类。

可选的 stream 属性指定此类型是否能够使用外部定义的运算符,如 QDataStream << 和 >>。如果等于 yes,这些运算符将作为当前类中的普通方法调用。

可选的 since 值用于指定此类型的 API 版本。

revision 属性可用于为每个类型指定修订版,以简化生成与 ABI 兼容的绑定。

可选的 属性 allow-threadexception-handing 指定函数修改的默认处理方式(见修改函数)。

可选的 generate-functions 属性定义了一个要用分号分隔的函数名或签名的最小列表,用于生成 这些函数。这允许限制生成绑定的函数。这同样适用于虚拟函数;因此,必须列出所有抽象函数以防止生成无法编译的代码。如果没有指定,将生成所有适合的函数的绑定。请注意,特殊函数(构造函数等)不能指定。

可选的 snake-case 属性允许覆盖 typesystem 元素上指定的值。

可选的 isNulloperator-bool 属性可以用来覆盖生成布尔转换的命令行设置(请参阅 Bool Cast)。

可选的 parent-management 属性指定该类用于构建由父对象和子对象组成的对象树,例如,类似于 QWidget 的用户界面类。对于这些类,将应用由 父关联启发式算法返回值启发式算法 启用的启发式算法来自动设置父关系。兼容性说明:在 shiboken 6 中,如果没有类型系统的类设置了此属性,则将应用所有类的启发式算法。在 shiboken 7 中,必须设置此属性。

可选的 polymorphic-id-expression 属性指定了一个表达式,用于检查基类指针是否为匹配的类型。例如,在 virtual eventHandler(BaseEvent *e) 函数中,这被用来构建一个匹配派生类的 Python 包装器(例如一个 MouseEvent 或类似的函数)。

可选的 polymorphic-name-function 指定了返回基类类型条目上派生类类型名称的函数的名称。通常,使用 typeid(ptr).name() 进行这一操作。然而,如果类型层级中没有虚拟函数,这将会失败。在这种情况下,需要一个函数,这个函数通常会根据某些类型枚举来做出决定。

接口类型#

此类型已弃用,不再有任何影响。请使用 object-type 代替。

容器类型#

container-type 节表示给定的类是一个容器,并必须使用属性 type 提供的某些转换帮助程序进行处理。它是 类型系统 节的一个子项,可能包含 转换规则 子项。

<typesystem>
    <container-type name="..."
        since="..."
        type ="..."
        opaque-containers ="..." />
</typesystem>

name 属性是完整的 C++ 类名称。该 type 属性用于指示将应用于容器的转换规则。可以是以下之一:listsetmapmulti-mappair

在 6.2 中弃用了一些类型: string-listlinked-listvectorstackqueue 等效于 listhashmulti-hash 分别等效于 mapmulti-map

可选的 opaque-containers 属性指定了一个用分号分隔的映射列表,这些映射表示从实例到类型名称的映射,为 不透明容器

<typesystem>
    <container-type name="std::array"
                    opaque-containers ="int,3:IntArray3;float,4:FloatArray4">

可选的 since 值用于指定此容器的 API 版本。

一些常见的标准容有 内置,还有许多有用的 预定义转换模板

不透明容器#

可以使用不透明容器元素将更多的不透明容器实例添加到现有的容器类型(内置或由包含模块中指定的容器类型)中。它是类型系统节点的子节点。

<typesystem>
    <oqaque-container name="..." opaque-containers ="..." />
</typesystem>

对于名称不透明容器属性,请参阅容器类型

typedef-type#

typedef-type节点允许在类型系统中指定typedef。它们通常等同于在包含的头文件中展开typedef,当尝试封装无法轻松扩展的库时,这通常很复杂。它是类型系统节点或其他类型节点的子节点。

<typesystem>
    <typedef-type name="..."
        source="..."
        since="..." />
</typesystem>

属性是源。示例

<namespace-type name='std'>
    <value-type name='optional' generate='no'/>\n"
</namespace-type>
<typedef-type name="IntOptional" source="std::optional&lt;int&gt;"/>

等同于

typedef std::optional<int> IntOptional;

可选的 since 值用于指定此类型的 API 版本。

custom-type#

custom-type节点简单地让解析器知道目标语言类型的存在,从而在尝试查找用于函数签名和其他地方的类型时避免错误。自定义类型的适当处理应由使用APIExractor的生成器来完成。它是类型系统节点的子节点。

<typesystem>
    <custom-type name="..."
        check-function="..." />
</typesystem>

名称属性是自定义类型的名称,例如,“PyObject”。

可选的检查函数属性可以用来指定一个布尔值检查函数,该函数用于在函数重载决策器中验证PyObject是否为指定类型。虽然Shiboken知道诸如PyLong_Check()PyType_Check()等常见检查函数,但对于通过注入代码处理的自定义类型的修改函数参数,提供这样的函数可能是有用的(参见替换类型)。

有关内置类型,请参阅CPython类型

smart-pointer-type#

smart pointer类型节点表示给定的类是一个智能指针,并且需要插入调用

getter

来访问指针的值。目前,这种用法仅限于函数返回值。引用计数方法指定了用于引用计数的方法的名称。它是类型系统节点或其他类型节点的子节点。

可选的实例化属性指定了智能指针包装器将为哪些实例化生成(逗号分隔列表)。默认情况下,这将针对代码解析找到的所有实例化发生。在链接不同模块时,可能会出现这种情况,因为同一实例化的包装器可能会生成到不同的模块中,从而导致冲突。提供实例化列表可以使指定哪些包装器将生成到特定模块成为可能。

<typesystem>
    <smart-pointer-type name="..."
        since="..."
        type="shared | handle | value-handle | unique"
        getter="..."
        ref-count-method="..."
        value-check-method="..."
        null-check-method="..."
        reset-method="..."
        instantiations="..."/>
    </typesystem>

可选的值检查方法属性指定了一个可以用来检查指针是否有值的方法。

可选的空指针检查方法属性指定了一个可以用来检查nullptr的方法。

可选的重置方法属性指定了一个可以用来清除指针的方法。

可选的实例化属性指定了一个以逗号分隔的实例化类型列表。如果为空,将生成代码中找到的所有实例化。类型名称可以可选地跟随一个等号和Python类型名称,例如:instantiations="int=IntPtr,double=DoublePtr"。也可以指定由 :: 分隔的命名空间。

可选属性 type 指定类型

shared

标准共享指针。

handle

一个基本的指针句柄,它有一个获取函数和 operator->

value-handle

一个带有获取函数的句柄,该函数返回一个值(与其它类型相比,在这里使用 T 而不是 T *)。它可以用于 std::optional

unique

一个标准的、唯一的指针(std::unique_ptr)或类似的可移动指针。为此需要指定 reset-method 属性。

下面的例子显示了 std::shared_ptr 的条目

<system-include file-name="memory"/>

<namespace-type name="std">
    <include file-name="memory" location="global"/>
    <modify-function signature="^.*$" remove="all"/>
    <enum-type name="pointer_safety"/>
    <smart-pointer-type name="shared_ptr" type="shared" getter="get"
                        ref-count-method="use_count"
                        instantiations="Integer">
        <include file-name="memory" location="global"/>
    </smart-pointer-type>
</namespace-type>

如果智能指针是命名空间 std 中唯一相关的类,它也可以被隐藏

<namespace-type name="std" visible="no">
    <smart-pointer-type name="shared_ptr" type="shared" getter="get"
                        ref-count-method="use_count"
                        instantiations="Integer">
        <include file-name="memory" location="global"/>
    </smart-pointer-type>
</namespace-type>

首先,使用 system-include 元素告诉shiboken实际解析包含类定义的系统包含文件。对于 namespace-typesmart-pointer-type,标准包含文件被用来覆盖内部实现头文件 shared_ptr.h。这创建了一些需要添加到模块的 CMakeLists.txt 的包装源。

function#

function 节表明给定的C++全局函数被映射到目标语言。它是 typesystem 节的一个子节点,并且可能包含一个 modify-function 子节点。

<typesystem>
    <function signature="..." rename="..." since="..."
              allow-thread="true | auto | false"
              doc-file = "..."
              exception-handling="off | auto-off | auto-on | on"
              overload-number="number"
              snake-case="yes | no | both" />
</typesystem>

存在限制:你不能使用 add-function 标签向现有函数添加函数重载。

使用可选的属性 since 指定函数引入的API版本。

使用可选的属性 rename 修改函数名称。

使用可选的属性 doc-file 指定由 \relates\headerfileqdoc 中指定的C++或 .qdoc 文件的基准名称,在该文件中添加并显示函数的文档,如果它是全局函数。此属性仅用于 qdoc

关于可选的属性 allow-threadexception-handlingoverload-numbersnake-case,请参阅 modify-function

system-include#

可选的 system-include 指定了要解析的系统包含文件的名称或系统包含路径(以斜杠结尾)。通常,C++ 代码解析器会跳过被认为是系统包含文件的包含文件。它的主要用例是公开 STL 库中的类。它是 typesystem 节的子节点。

<typesystem>
    <system-include file-name="memory"/>
    <system-include file-name="/usr/include/Qt/"/>
</typesystem>

条件处理#

提供简单的处理指令来根据关键字的存在包括或排除部分。语法为

<?if keyword !excluded_keyword ?>
   ...
<?endif?>

有预定义的关键字表示操作系统(windowsunixdarwin)。

传递给 language-level 命令行选项的语言级别反映了 c++11c++14c++17c++20

传递给 –drop-type-entries 命令行选项的类名也是预定义的,以 no_ 为前缀。这允许例如将引用这些类的函数封装在 <?if !no_ClassName?><?endif?> 中。

可以使用 –keywords 命令行选项指定其他关键字。

定义实体#

可以使用简单的处理指令来定义实体

<?entity name value?>
<text>&name;</text>

这允许在结合使用 条件处理 的同时根据平台定义函数签名。

私有类型#

object-typevalue-type 条目标记为私有会导致除了公共模块头之外,还会为它们生成单独的私有模块头。

这可以用于不参考依赖模块的类,有助于防止例如需要它们的私有 C++ 头的传播。