六、SWIG 之 代码插入

有时需要在 SWIG 生成的结果包装器文件中插入特殊代码。例如,你可能希望包含其他 C 代码以执行初始化或其他操作。插入代码有四种常用方法,但首先了解如何构造 SWIG 的输出很有用。

一、SWIG的输出

当 SWIG 创建其输出 C/C++ 文件时,它将分为五个部分,分别对应于运行时代码、头文件、包装器函数和模块初始化代码(按此顺序)。

开始部分 : 用户的占位符,用于将代码放在 C/C++ 包装器文件的开头。这通常用于定义后续部分中使用的预处理器宏。
运行时代码: 此代码是 SWIG 的内部代码,用于包含类型检查和其他模块使用的支持函数。
头文件部分: 这是用户定义的支持代码,已由 %{...%} 指令包含。通常这包括头文件和其他辅助函数。
包装器函数: 这些是 SWIG 自动生成的包装器。
模块初始化: SWIG 生成的函数,用于在加载时初始化模块。

二、代码插入块

说明: 尚未研究出来,待后续继续研究

%insert 指令允许将代码块插入生成代码的给定部分。它可以使用以下两种方式之一:

%insert("section") "filename"
%insert("section") %{ ... %}

第一种将把给定 filename 中文件的内容转储到命名的 section 中。第二种将大括号之间的代码插入到命名的 section 中。例如,以下内容将代码添加到运行时部分:

%insert("runtime") %{
  ... code in runtime section ...
%}

有 5 个部分,但是,一些目标语言在附加部分中添加,其中一些导致代码生成到目标语言文件而不是 C/C++ 包装器文件。目标语言章节中提供了这些内容。以代码段命名的宏可用作附加指令,并且通常使用这些宏指令而不是 %insert。例如,使用 %runtime 而不是 %insert("runtime")。生成的 C/C++ 包装器文件中的有效部分和部分的顺序如下所示:

%begin %{
  ... code in begin section ...
%}
 
%runtime %{
  ... code in runtime section ...
%}
 
%header %{
  ... code in header section ...
%}
 
%wrapper %{
  ... code in wrapper section ...
%}
 
%init %{
  ... code in init section ...
%}

三、内联代码块

由于编写辅助函数的过程相当普遍,因此有一种特殊的内联形式的代码块,其使用方法如下:

// example.c

typedef struct Vector {
    int x, y, z;
} Vector;
/* example.i */
%module example

%{
#include "example.h"
%}

%inline %{
    Vector *new_Vector(int x, int y, int z) {
        Vector *v;
        v = (Vector *)malloc(sizeof(Vector));
        v->x = x;
        v->y = y;
        v->z = z;
        printf("v->x=%d,v->y=%d,v->z=%d \n", v->x, v->y, v->z);
        return v;
    }
    void delete_Vector(Vector *v) {
        free(v);
    }
%}

%inline 指令将逐字输入的所有代码插入到接口文件的头文件部分中。然后由 SWIG 预处理器和解析器解析代码。因此,上面的示例仅使用一个声明创建一个新命令 new_Vector。由于 %inline%{...%} 块内的代码被赋予 C 编译器和 SWIG,因此在 %{...%} 块中包含任何 SWIG 指令是非法的。

四、初始化块

当代码包含在 %init 部分中时,它会直接复制到模块初始化函数中。例如,如果你需要在模块加载时执行一些额外的初始化,你可以这样写:

// example.c

int init_variables()
{
    int a = 10;
    return a;
}
/* example.i */
%module example

%{
#include "example.h"
%}

%init %{
  init_variables();
%}
# script.py

import example
vector = example.init_variables()
print(vector)  # 10

 

posted on 2022-11-22 17:22  软饭攻城狮  阅读(269)  评论(0编辑  收藏  举报

导航