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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...