八、SWIG 之 简单案例总结

/* example.i */
%module example

%include "example.h"

%include "cpointer.i"
%include "carrays.i"
%include "cmalloc.i"
%include "cdata.i"

%inline %{
    typedef unsigned char          GM_UINT8;
    typedef unsigned int        GM_UINT32;
%}

%inline %{
    extern GM_UINT32 variable;
    extern void print_array(GM_UINT32 x[10]);
%}


%{
    void test_function();
%}

%pointer_functions(GM_UINT32, GM_UINT32_p)
%array_functions(GM_UINT8, GM_UINT8_Array);

extern void add(GM_UINT32 x, GM_UINT32 y, GM_UINT32 *result);

一、%module

%module + 文件名:  用于生成的 python 文件的文件名

/* example.i */

%module expample
// swig -pythopn example.i 之后就会生成 example.py文件, 这个文件是脚本调用C的一个接口文件。脚本文件调用 example.py, 这个文件封装了 C 的接口,、
会帮助我们调用 example.pyd 文件,example.pyd 文件的内容就是 C 语言生成的给 Python 使用的 dll(windows上是pyd)文件。

二、%include、#include

include + 文件名: 用于引入其他的 .h 文件。
不同的是:
  %{ #include }% #include引入的是自己写的 .h 场景较多, #include确保生成的C/C++代码包含该标头。会直接映射到SWIG的头文件中,作用和C/C++中类似;
  %include相比之下,%include是一个SWIG指令, 一般用于引入SWIG 内置的 .h 较多。它告诉SWIG在继续之前处理该头文件.这样,SWIG将了解(并生成包装)该头文件中声明的类型和函数。换句话说, %include既引入了头文件的功能,还会让 SWIG 处理其内部的一些函数和操作。如cdata.i 中 cdata、memove函数等。

三、%{ ... %}

%{
...
%}

%{ ... %} : ...这部分里面的内容由SWIG生成的文件中一字不差被使用,以便生成的文件将被编译,通常放置任何包含和定义等,以便生成的文件进行编译。 也就是 SWIG 会将 ... 直接复制到 SWIG 的接口文件中。差不多就类似于将内部的一些申明直接映射复制到接口文件中。接口文件的函数声明也直接复制过去进行函数声明,但是没有函数实现的部分。

四、%inline %{... %}

%inline指令将所有跟随文字的代码插入到接口文件的标题部分中.然后由SWIG预处理器和解析器解析代码.

所以它%inline %{ ... %}做了两件事:它将声明放在生成的包装器文件中,它使SWIG生成包装器代码,以便可以从目标语言(Python,Lua,无论如何)调用块中的函数等.情况并非如此%{ ... }%:此类块中的代码不会被包装,只是在生成的包装器文件中逐字转储。可以这样理解, %inline 既实现了 %{...%}的功能,同时也有对函数进行实现的操作实现。同时内联代码块内也可以自定义一些函数功能。

五、全局变量

SWIG 的全局变量以及全局函数有点类似于直接产生 SWIG 玩不的接口实现,没有声明这一步,所以在某种层面上可以理解:  全局变量 + %{ ... %} ==  %inline。 但是全局变量想要直接声明必须先定义,所以全局变量一定要在 %inline 中定义才能使用。 函数的话可以直接定义并能够调用

六、函数声明与调用代码

/* example.h */
typedef unsigned int  GM_UINT32;


typedef struct Vector {
    GM_UINT32 x, y, z;
} Vector;
/* example.c */
#include<stdio.h>
#include<string.h>
typedef unsigned char  GM_UINT8;
typedef unsigned int  GM_UINT32;

GM_UINT32 variable = 10;


void add_function(GM_UINT32 x, GM_UINT32 y, GM_UINT32 *result) {
    *result = x + y;
}

void print_array(GM_UINT32 x[10]) {
    int i;
    for (i = 0; i < 10; i++) {
        printf("[%d] = %d\n", i, x[i]);
    }
}

void test_function()
{
    printf("variable = %d\n", variable);
}
# script.py

import example

print(example.cvar.variable)  # 10


c = example.new_GM_UINT32_p()
example.add_function(3, 4, c)
print(example.GM_UINT32_p_value(c))  # 7
example.delete_GM_UINT32_p(c)

_data = [1, 2, 3, 4, 5, 6, 7, 8]
array = example.new_GM_UINT8_Array(10)
[example.GM_UINT8_Array_setitem(array, i, _data[i]) for i in range(len(_data))]
b = example.cdata(array, 10)  # 从缓存中取值
print((b,))  # ('\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00',)
c = example.new_GM_UINT8_Array(100)
example.memmove(c, b)
print(example.GM_UINT8_Array_getitem(c, 1))  # 2

 

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

导航