当前位置:网站首页>SWIG tutorial "two"
SWIG tutorial "two"
2022-08-10 14:54:00 【Ah cool studio】
变量属性
使用immutableCreate read-only fields,Variables edited using this field have only counterparts in the corresponding target languageGetX接口,无法对值进行修改.
A variable is once marked as immutable之后,Only explicitly re-specified asmutable,Otherwise it is always a read-only variable
The %immutable directive enables read-only mode until it is explicitly disabled using the %mutable directive
// File : interface.i
int a; // Can read/write
%immutable;
int b, c, d; // Read only variables
%mutable;
double x, y; // read/write
Compatibility note: Read-only access used to be controlled by a pair of directives %readonly and %readwrite. Although these directives still work, they generate a warning message.
Simply change the directives to %immutable; and %mutable; to silence the warning. Don't forget the extra semicolon
重命名
Sometimes when converting the corresponding language to the target language,due to different keywords,Variables that work normally in that language may be keywords in the target language,这个时候可以使用rename进行重命名.
// interface.i
// will be in the source languageprint函数重命名为my_printThis will pass in the target languagemy_printto call in the source languageprint
%rename(my_print) print;
extern void print(const char *);
%rename(foo) a_really_long_and_annoying_name;
extern int a_really_long_and_annoying_name;
renameThe scope is from the beginning of the declaration until the end of the file,So if you want that header file to be renamed, you need to ensure that the header file is importedrename之后
%rename(my_print) print;
%rename(foo) a_really_long_and_annoying_name;
%include "header.h"
// It doesn't matter if you add double quotes or not,But when the renamed name isC++的关键字是,Adding double quotes becomes necessary
%rename("foo_short") foo(short);
%rename(foo_long) foo(long);
void foo(int);
void foo(short); // Accessed as foo_short()
void foo(long); // Accessed as foo_long()
Being able to name a single one is usually enough,但swig的功能远不止于此,Batch naming can be done by matching,Such as adding a prefix to all functions
%rename("myprefix_%s") ""; // print -> myprefix_print
Modify all snake case names to camel case names
%rename("%(lowercamelcase)s") ""; // foo_bar -> fooBar; FooBar -> fooBar
Eliminate some characters in the name from being used
%rename("%(strip:[wx])s") ""; // wxHello -> Hello; FooBar -> FooBar
Rename operator overloaded functions
%rename(__add__) Complex::operator+;
If operator overloading is required for friend function or global function overloading, it is renamed as follows
%rename(op_j) ::operator+;

It also supports matching using regular expressions
// Strip the wx prefix from all identifiers except those starting with wxEVT
%rename("%(regex:/wx(?!EVT)(.*)/\\1/)s") ""; // wxSomeWidget -> SomeWidget
// wxEVT_PAINT -> wxEVT_PAINT
// Apply a rule for renaming the enum elements to avoid the common prefixes
// which are redundant in C#/Java
%rename("%(regex:/^([A-Z][a-z]+)+_(.*)/\\2/)s", %$isenumitem) ""; // Colour_Red -> Red
// Remove all "Set/Get" prefixes.
%rename("%(regex:/^(Set|Get)(.*)/\\2/)s") ""; // SetValue -> Value
// GetValue -> Value
Ignore
使用ignore可以指示swigIgnore things that don't need encapsulation
%ignore print; // Ignore all declarations named print
%ignore MYMACRO; // Ignore a macro
...
#define MYMACRO 123
void print(const char *);
You can choose to ignore most symbols,Only a small part of it is encapsulated
Using the techniques described above it is possible to ignore everything in a header and then selectively wrap a few chosen methods or classes. For example, consider a header, myheader.h
which has many classes in it and just the one class called Star is wanted within this header, the following approach could be taken:
%ignore ""; // Ignore everything
// Unignore chosen class 'Star'
%rename("%s") Star;
// As the ignore everything will include the constructor, destructor, methods etc
// in the class, these have to be explicitly unignored too:
%rename("%s") Star::Star;
%rename("%s") Star::~Star;
%rename("%s") Star::shine; // named method
%include "myheader.h"
It can also be ignored by type
%rename($ignore, %$isclass) ""; // Only ignore all classes
%rename("%s") Star; // Unignore 'Star'
%include "myheader.h"
回调函数
Some functions that need to be passed a callback,需要提前声明,The function implemented by the target function cannot be passed in directly
/* Function with a callback */
int binary_op(int a, int b, int (*op)(int, int));
/* Some callback functions */
// Pass in the callback function to be used
%constant int add(int, int);
%constant int sub(int, int);
%constant int mul(int, int);
Once declared as a callback function,Will not be used as a normal function in the target function,If a function is called as a callback function, it also wants to be called as a normal function,It can be declared as follows
/* Function with a callback */
int binary_op(int a, int b, int (*op)(int, int));
/* Some callback functions */
%callback("%s_cb");
int add(int, int);
int sub(int, int);
int mul(int, int);
%nocallback;
Structure and Analysis
Swig 为每个C++The class generates default constructors and parsing functions,If it is not needed, it can be disabled using parameter options or directives
If you don't want SWIG to generate default constructors for your interfaces, you can use the %nodefaultctor directive or the -nodefaultctor command line option. For example:
swig -nodefaultctor example.i
Or
%module foo
...
%nodefaultctor; // Don't create default constructors
... declarations ...
%clearnodefaultctor; // Re-enable default constructors
Or you can be more precise to specify which class does not create a constructor
%nodefaultctor Foo; // No default constructor for Foo
...
struct Foo { // No default constructor generated.
};
struct Bar { // Default constructor generated.
};
虽然,Not creating an analysis function often results in memory leaks,但是swigStill allows you to control not to create the parsing function throughnodefaultdtorSpecifies the type that does not require a parsing function
%nodefaultdtor Foo; // No default/implicit destructor for Foo
...
struct Foo { // No default destructor is generated.
};
struct Bar { // Default destructor generated.
};
Note: There are also the-nodefault option and %nodefault directive, which disable both the default or implicit destructor generation. This could lead to memory leaks across the target
languages, and it is highly recommended you don't use them
限制
虽然siwgCan handle most of themC++语法,但swig并不是完整的C++解析器,There is still a lot of syntax that isswig无法解析的.
Non-conventional type declarations. For example, SWIG does not support declarations such as the following (even though this is legal C):
/* Non-conventional placement of storage specifier (extern) */
const int extern Number;
/* Extra declarator grouping */
Matrix (foo); // A global variable
/* Extra declarator grouping in parameters */
void bar(Spam (Grok)(Doh));
为C++The class adds member functions
很多CA struct of type cannot bind member functions,But in other functions,For convenienceswig支持为CTyped structures bind additional member functions to aid in the creation and use of structures,这时就要用到%extend指令了
/* file : vector.h */
...
typedef struct Vector {
double x, y, z;
} Vector;
通过extend指令为C++Add a constructor to a type of struct
// file : vector.i
%module mymodule
%{
#include "vector.h"
%}
%include "vector.h" // Just grab original C header file
%extend Vector { // Attach these functions to struct Vector
Vector(double x, double y, double z) {
Vector *v;
v = (Vector *) malloc(sizeof(Vector));
v->x = x;
v->y = y;
v->z = z;
return v;
}
~Vector() {
free($self);
}
double magnitude() {
return sqrt($self->x*$self->x+$self->y*$self->y+$self->z*$self->z);
}
void print() {
printf("Vector [%g, %g, %g]\n", $self->x, $self->y, $self->z);
}
};
但是extend指令只能用于struct上,Cannot be used for passingtypedefafter the type name
typedef struct Integer {
int value;
} Int;
%extend Integer { ... } /* Correct name */
%extend Int { ... } /* Incorrect name */
struct Float {
float value;
};
typedef struct Float FloatValue;
%extend Float { ... } /* Correct name */
%extend FloatValue { ... } /* Incorrect name */
有一种特殊情况除外,那就是当typedefan anonymous class,是可以使用extend的
typedef struct {
double value;
} Double;
%extend Double { ... } /* Okay */
代码注入
swig代码输出格式
swig输出的C/C++The code will be divided into5部分
Begin section.
A placeholder for users to put code at the beginning of the C/C++ wrapper file. This is most often used to define preprocessor macros that are used in later sections.
Runtime code.
This code is internal to SWIG and is used to include type-checking and other support functions that are used by the rest of the module.
Header section.
This is user-defined support code that has been included by the %{ ... %} directive. Usually this consists of header files and other helper functions.
Wrapper code.
These are the wrappers generated automatically by SWIG.
Module initialization.
The function generated by SWIG to initialize the module upon loading.
Code injection instructions
Command injection format:
// 将在sectionPartially injected code,section为begin runtime header wrapper init等字段
%insert("section") "filename"
// Injects the content of the following code segment into the specified segment
%insert("section") %{ ... %}
当然除了使用insert指令,sectionThe name itself is also an instruction,也可以sectionAs an instruction, code injection is performed on the specified code segment
For example, %runtime is used instead of %insert("runtime").
%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 ...
%}
说明:Actually used often%{....%},其实是%header %{...%}的简写
The bare %{ ... %} directive is a shortcut that is the same as %header %{ ... %}
Init Sections are used by some code that needs to be initialized.
辅助函数
In actual use, the function of code injection is often used to write auxiliary functions
%{
/* Create a new vector */
static Vector *new_Vector() {
return (Vector *) malloc(sizeof(Vector));
}
%}
// Now wrap it
Vector *new_Vector();
In order to simplify the writing of auxiliary code,引入了inline指令,The command is used as follows:
凡是被inline标记的代码段,It is equivalent to the effect of writing it by hand in both the code and the package:
%inline %{
/* Create a new vector */
Vector *new_Vector() {
return (Vector *) malloc(sizeof(Vector));
}
%}
等效于
%{
/* Create a new vector */
Vector *new_Vector() {
return (Vector *) malloc(sizeof(Vector));
}%
}
/* Create a new vector */
Vector *new_Vector() {
return (Vector *) malloc(sizeof(Vector));
}
但是需要注意的是,inlineOnly valid for functions and variables,Whether references to header files are encapsulated,Still need the original way,在代码块中使用#include 引入头文件,The header files that need to be encapsulated into object code need to be used outside the code block%includeinstruction to informswigThis header file needs to be encapsulated
说明:编译选项-Dmain=oldmainIn fact, it is used in the macro definition replacement process,A high-speed preprocessor willmainReplace it with the symbol after the equals sign
边栏推荐
- leetcode 739. Daily Temperatures 每日温度(中等)
- EVE模拟器的使用-带图超详细(学网络用)「建议收藏」
- win2012安装Oraclerac失败
- 强意识 压责任 安全培训筑牢生产屏障
- 等保2.0一个中心三重防护指的是什么?如何理解?
- 领域驱动模型设计与微服务架构落地-从项目去剖析领域驱动
- Error: Rule can only have one resource source (provided resource and test + include + exclude)
- 串口服务器调试助手使用教程,串口调试助手使用教程【操作方式】
- Go Context基本使用
- SQL学习(基础)
猜你喜欢

2022年网络安全培训火了,缺口达95%,揭开网络安全岗位神秘面纱

使用Uiautomator2进行APP自动化测试

【Gazebo入门教程】第三讲 SDF文件的静/动态编程建模

正则表达式(包含各种括号,echo,正则三剑客以及各种正则工具)

How does IT Xiaobai learn PHP systematically

Analysys and the Alliance of Small and Medium Banks jointly released the Hainan Digital Economy Index, so stay tuned!

Send a post request at the front desk can't get the data

基于ArcGIS水文分析、HEC-RAS模拟技术在洪水危险性及风险评估

等保2.0一个中心三重防护指的是什么?如何理解?

12海里、24海里、200海里的意义及名称
随机推荐
1004(树状数组+离线操作+离散化)
PHP judges whether the file has content, and if there is no content, copy another file to write
redhat替换yum源时redhat.repo无法删除或无法禁用的问题解决方法
2022年网络安全培训火了,缺口达95%,揭开网络安全岗位神秘面纱
PyTorch multi-machine multi-card training: DDP combat and skills
公网IP和内网IP的区别[通俗易懂]
SWIG教程《二》
司空见惯 - 股市狠狠下跌后,何時能反弹?
High-paid programmers & interview questions series 135 How do you understand distributed?Do you know CAP theory?
文件系统设计
解题-->在线OJ(十九)
舵机内部结及工作原理浅析[通俗易懂]
Digital Collection Platform System Development Practice
systemui屏蔽通知栏
Mysql语句分析、存储引擎、索引优化等详情
Unfinished mathematics test paper ----- test paper generator (Qt includes source code)
SWIG教程《四》-go语言的封装
CSP-J1 CSP-S1 初赛 第1轮(2022.08.09)
【MindSpore易点通机器人-02】设计与技术选型
Steam教育在新时代中综合学习论