SWIG 3 中文手冊——13. 約定

来源:https://www.cnblogs.com/xuruilong100/archive/2020/06/29/13210798.html
-Advertisement-
Play Games

13 約定 A common problem that arises when wrapping C libraries is that of maintaining reliability and checking for errors. The fact of the matter is tha ...


目錄

13 約定

A common problem that arises when wrapping C libraries is that of maintaining reliability and checking for errors. The fact of the matter is that many C programs are notorious for not providing error checks. Not only that, when you expose the internals of an application as a library, it often becomes possible to crash it simply by providing bad inputs or using it in a way that wasn't intended.

This chapter describes SWIG's support for software contracts. In the context of SWIG, a contract can be viewed as a runtime constraint that is attached to a declaration. For example, you can easily attach argument checking rules, check the output values of a function and more. When one of the rules is violated by a script, a runtime exception is generated rather than having the program continue to execute.

包裝 C 庫時出現的常見問題是維護可靠性和檢查錯誤。事實是,許多 C 程式因不提供錯誤檢查而臭名昭著。不僅如此,當你將應用程式的內部結構公開為一個庫時,通常可能會因提供錯誤的輸入或以非預期的方式使用它而使其崩潰。

本章介紹 SWIG 對軟體約定的支持。在 SWIG 的上下文中,約定可以視為附加到聲明的運行時約束。例如,你可以輕鬆地附加參數檢查規則,檢查函數的輸出值等等。如果腳本違反了其中一個規則,則會生成運行時異常,而不是讓程式繼續執行。

13.1 %contract 指令

Contracts are added to a declaration using the %contract directive. Here is a simple example:

使用 %contract 指令將約定添加到聲明中。這是一個簡單的示例:

%contract sqrt(double x) {
require:
  x >= 0;
ensure:
  sqrt >= 0;
}

...
double sqrt(double);

In this case, a contract is being added to the sqrt() function. The %contract directive must always appear before the declaration in question. Within the contract there are two sections, both of which are optional. The require: section specifies conditions that must hold before the function is called. Typically, this is used to check argument values. The ensure: section specifies conditions that must hold after the function is called. This is often used to check return values or the state of the program. In both cases, the conditions that must hold must be specified as boolean expressions.

In the above example, we're simply making sure that sqrt() returns a non-negative number (if it didn't, then it would be broken in some way).

Once a contract has been specified, it modifies the behavior of the resulting module. For example:

在這種情況下,將約定添加到 sqrt() 函數中。%contract 指令必須始終出現在相關聲明之前。約定中有兩個部分,兩者都是可選的。require: 部分指定了在調用函數之前必須滿足的條件。通常,它用於檢查參數值。ensure: 部分指定了在調用函數後必須滿足的條件。通常用於檢查返回值或程式狀態。在這兩種情況下,必須滿足的條件都必須指定為布爾表達式。

在上面的示例中,我們只是確保 sqrt() 返回一個非負數(如果不返回,那麼它將以某種方式被破壞)。

指定約定後,它將修改結果模塊的行為。例如:

>>> example.sqrt(2)
1.4142135623730951
>>> example.sqrt(-2)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
RuntimeError: Contract violation: require: (arg1>=0)
>>>

13.2 %contract 與類

The %contract directive can also be applied to class methods and constructors. For example:

%contract 指令也可以應用於類方法和構造函數。例如:

%contract Foo::bar(int x, int y) {
require:
  x > 0;
ensure:
  bar > 0;
}

%contract Foo::Foo(int a) {
require:
  a > 0;
}

class Foo {
public:
  Foo(int);
  int bar(int, int);
};

The way in which %contract is applied is exactly the same as the %feature directive. Thus, any contract that you specified for a base class will also be attached to inherited methods. For example:

%contract 的應用方式與 %feature 指令完全相同。因此,你為基類指定的任何約定也將附加到繼承的方法。例如:

class Spam : public Foo {
public:
  int bar(int, int);    // Gets contract defined for Foo::bar(int, int)
};

In addition to this, separate contracts can be applied to both the base class and a derived class. For example:

除此之外,可以將單獨的約定同時應用於基類和派生類。例如:

%contract Foo::bar(int x, int) {
require:
  x > 0;
}

%contract Spam::bar(int, int y) {
require:
  y > 0;
}

class Foo {
public:
  int bar(int, int);   // Gets Foo::bar contract.
};

class Spam : public Foo {
public:
  int bar(int, int);   // Gets Foo::bar and Spam::bar contract
};

When more than one contract is applied, the conditions specified in a "require:" section are combined together using a logical-AND operation. In other words conditions specified for the base class and conditions specified for the derived class all must hold. In the above example, this means that both the arguments to Spam::bar must be positive.

當應用多個約定時,使用邏輯與運算將 require: 部分中指定的條件組合在一起。換句話說,為基類指定的條件和為派生類指定的條件都必須成立。在上面的示例中,這意味著 Spam::bar 的兩個參數都必須為正。

13.3 約定集成與 %aggregate_check

Consider an interface file that contains the following code:

考慮包含以下代碼的介面文件:

#define  UP     1
#define  DOWN   2
#define  RIGHT  3
#define  LEFT   4

void move(SomeObject *, int direction, int distance);

One thing you might want to do is impose a constraint on the direction parameter to make sure it's one of a few accepted values. To do that, SWIG provides an easy to use macro %aggregate_check() that works like this:

你可能想做的一件事是對 direction 參數施加約束,以確保它是少數幾個可接受的值之一。為此,SWIG 提供了一個易於使用的巨集 %aggregate_check(),其工作方式如下:

%aggregate_check(int, check_direction, UP, DOWN, LEFT, RIGHT);

This merely defines a utility function of the form

只是定義一個工具函數

int check_direction(int x);

That checks the argument x to see if it is one of the values listed. This utility function can be used in contracts. For example:

這將檢查參數 x 以查看其是否為列出的值之一。可以在約定中使用此實用程式函數。例如:

%aggregate_check(int, check_direction, UP, DOWN, RIGHT, LEFT);

%contract move(SomeObject *, int direction, in) {
require:
  check_direction(direction);
}

#define  UP     1
#define  DOWN   2
#define  RIGHT  3
#define  LEFT   4

void move(SomeObject *, int direction, int distance);

Alternatively, it can be used in typemaps and other directives. For example:

另外,它可以在類型映射和其他指令中使用。例如:

%aggregate_check(int, check_direction, UP, DOWN, RIGHT, LEFT);

%typemap(check) int direction {
  if (!check_direction($1)) SWIG_exception(SWIG_ValueError, "Bad direction");
}

#define  UP     1
#define  DOWN   2
#define  RIGHT  3
#define  LEFT   4

void move(SomeObject *, int direction, int distance);

Regrettably, there is no automatic way to perform similar checks with enums values. Maybe in a future release.

遺憾的是,沒有自動的方法可以對枚舉值執行類似的檢查。也許在將來的版本中可以。

13.4 註意事項

Contract support was implemented by Songyan (Tiger) Feng and first appeared in SWIG-1.3.20.

約定支持由 Songyan(Tiger)Feng 實施,並首次出現在 SWIG-1.3.20 中。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 基於Nexus搭建私服 1. 工作流程 2. 倉庫類型 hosted 私服倉庫 proxy倉庫 遠程倉庫 group倉庫 組倉庫,裡面可以設置組合多個倉庫。按順序獲取jar。 3. 預設倉庫 安裝好了Nexus後,會內置幾個maven的預設倉庫。可自定義倉庫。 maven-central proxy ...
  • 1 前言 相信不少人聽過這麼一句話: 人類的本質是復讀機。 在軟體開發領域也一樣,我們總是想尋找更好地方式複製優秀的邏輯或系統。最核心的方法是抽取通用邏輯和組件,把差異化的東西介面化或配置化,達到復用的效果。如Java的Build Once, Run Everywhere,還有Spring的強大的抽 ...
  • 引用原文 原文鏈接 http://marcio.io/2015/07/handling-1-million-requests-per-minute-with-golang/ 問題描述 直入本文要描述的問題:網站流量上來了,高併發負載是不可避免滴問題了,當服務端需要處理大量耗時的任務時,我們一般都會考 ...
  • 一、可移植類型舉例 1.系統不支持“精確寬度整數類型”怎麼辦? 最小寬度類型:一些類型名保證所表示的類型一定是至少有指定寬度的最小整數類型。 使用上述定義的類型,例如:int_least8_t是可以容納8位有符號整數值類型中的寬度最小的類型的一個別名,如果某系統的最小整數類型是16位,可能不會定義i ...
  • Reactor 操作符 上篇文章我們將 Flux 和 Mono 的操作符分了 11 類,我們來繼續學習轉換類操作符的第 2 篇。 轉換類操作符 轉換類的操作符數量最多,平常過程中也是使用最頻繁的。 Flux#concatMap 將響應式流中元素順序轉換為目標類型的響應式流,之後再將這些流連接起來。該 ...
  • pom.xml中引入 <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.1.2</version> </dependency> 在applicati ...
  • 1.判斷提交方式 if(request.getMethod().equals("POST")) 2.返回json @ResponseBody 3.限定請求方式 @RequestMapping(value="/login",method= RequestMethod.POST) 4.session / ...
  • 安裝typora 下載地址:https://www.typora.io/ 找到配置文件 picgo 的預設配置文件為~/.picgo/config.json。其中~為用戶目錄。不同系統的用戶目錄不太一樣。 linux 和 macOS 均為~/.picgo/config.json。 windows 則 ...
一周排行
    -Advertisement-
    Play Games
  • Dapr Outbox 是1.12中的功能。 本文只介紹Dapr Outbox 執行流程,Dapr Outbox基本用法請閱讀官方文檔 。本文中appID=order-processor,topic=orders 本文前提知識:熟悉Dapr狀態管理、Dapr發佈訂閱和Outbox 模式。 Outbo ...
  • 引言 在前幾章我們深度講解了單元測試和集成測試的基礎知識,這一章我們來講解一下代碼覆蓋率,代碼覆蓋率是單元測試運行的度量值,覆蓋率通常以百分比表示,用於衡量代碼被測試覆蓋的程度,幫助開發人員評估測試用例的質量和代碼的健壯性。常見的覆蓋率包括語句覆蓋率(Line Coverage)、分支覆蓋率(Bra ...
  • 前言 本文介紹瞭如何使用S7.NET庫實現對西門子PLC DB塊數據的讀寫,記錄了使用電腦模擬,模擬PLC,自至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1.Windows環境下鏈路層網路訪問的行業標準工具(WinPcap_4_1_3.exe)下載鏈接:http ...
  • 從依賴倒置原則(Dependency Inversion Principle, DIP)到控制反轉(Inversion of Control, IoC)再到依賴註入(Dependency Injection, DI)的演進過程,我們可以理解為一種逐步抽象和解耦的設計思想。這種思想在C#等面向對象的編 ...
  • 關於Python中的私有屬性和私有方法 Python對於類的成員沒有嚴格的訪問控制限制,這與其他面相對對象語言有區別。關於私有屬性和私有方法,有如下要點: 1、通常我們約定,兩個下劃線開頭的屬性是私有的(private)。其他為公共的(public); 2、類內部可以訪問私有屬性(方法); 3、類外 ...
  • C++ 訪問說明符 訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關鍵字。它們用於封裝類數據並保護其免受意外修改或濫用。 三種訪問說明符: public:允許從類外部的任何地方訪問成員。 private:僅允許在類內部訪問成員。 protected:允許在類內部及其派生類中訪問成員。 示 ...
  • 寫這個隨筆說一下C++的static_cast和dynamic_cast用在子類與父類的指針轉換時的一些事宜。首先,【static_cast,dynamic_cast】【父類指針,子類指針】,兩兩一組,共有4種組合:用 static_cast 父類轉子類、用 static_cast 子類轉父類、使用 ...
  • /******************************************************************************************************** * * * 設計雙向鏈表的介面 * * * * Copyright (c) 2023-2 ...
  • 相信接觸過spring做開發的小伙伴們一定使用過@ComponentScan註解 @ComponentScan("com.wangm.lifecycle") public class AppConfig { } @ComponentScan指定basePackage,將包下的類按照一定規則註冊成Be ...
  • 操作系統 :CentOS 7.6_x64 opensips版本: 2.4.9 python版本:2.7.5 python作為腳本語言,使用起來很方便,查了下opensips的文檔,支持使用python腳本寫邏輯代碼。今天整理下CentOS7環境下opensips2.4.9的python模塊筆記及使用 ...