2012年9月6日 星期四

perl xs及swig初探

XS

  1. XS是用來供為perl呼叫C函式(反之亦可)的介面,可建立程式庫供動態載入或靜態連結;此一介面的描述語言,我們稱為"XS語言"。
  2. XSUB是XS介面的基本單位,其中sub即為subroutine(副程式)之縮寫。
  3. xsubpp是"XS語言"的編譯器,將"XS語言"編譯為C語言的函數定義,以做為perl及C之間呼叫函數的橋樑。
  4. 這黏著劑一般的程式碼,對參數及傳回值在背景進行轉換,參數可以傳值或傳址方式被修改。
  5. 為了簡化流程,我們可以用"XS語言"來撰寫介面,然後以xsubpp編譯之。"XS語言"讓我們可以表達在perl及C當中副程式被呼叫的"簽名"的對應。兩這兩者的型態一樣時,還有一種叫做h2xs的工具程式,用來將整個標頭檔(*.h)對應為"XS語言"檔。
  6. 在"XS語言"中,typemaps指令用來描述如何將C函式的參數和傳回直轉換為perl型態,反之亦然。perl本身帶有的預設typemap,可以處理常見的C型態,但是除此之外的typemap仍然需要手動撰寫。
  7. XS格式的檔案,一開始是一個C語言的節段,直到出現第一個MODULE=指令為止;之後則可以是其它的XS指令或是XSUB定義,這裏使用的語言就是之前曾經提到過的"XS語言"。

swig

Dave Beazley's SWIG可能提供了更方便的機制,請造訪 http://www.swig.org/ ,至於中文版可參考 http://www.swig.org/translations/chinese/index.html

在進行利用swig產生標頭之前,先來稍微了解一下流程,參考 SWIG (Simplified Wrapper and Interface Generator)

why

在幾個以國數字為標題的項目中,我們感興趣的是一及二。一的部分就是單純只有C檔,然後為它撰寫 i 檔。這個做法當然不像是一個好主意,至少通常現在的函式庫中都寫好了 h 檔。因此二的部分就是單純利用此 h 檔,產生 wrapper ,將它與函式庫一起編譯為 so 檔。要注意的是此 so 檔必需要在程式執行前先行手動載入。(此外五中使用了標準函式庫,其作法也值得參考一下。)不過即然可以直接由 h 檔產生介面,那為何還要手寫 i 檔呢?答案就在官方文件中~~

先來研究一下官方的文件。在抓下來的swig解開後,swig-2.0.8/Doc/Manual/Sections.html#Sections 有文件的目錄,16章以前講的是一般性的東西,17章以後針對個別的語言講解,其中perl的部分在第31章。第五章是官方建議必讀,像為何要另外撰寫 i 檔,答案在 5.7.4 中。第一個原因就是控制 scope,很多函數沒有必要去呈現成為介面,而且全部都產生介面的話會形成無用的巨大檔案;因此, i 檔可以提供精確的控制、組織;另一方面,swig有它的局限性,無法轉譯的介面,仍然需要在 i 檔中予以處理;最後,它本身就可以做為一個文件,使用者不必去挖 h 檔裏面的資訊,就可以了解如何使用介面。

how

接下來看看怎麼進行。5.7.1講解流程:
  1. (從 h 檔中)找出所要包裝的函數(和 h 檔)
  2. 建立 i 檔
  3. (從 h 檔中)複製函數宣告到 i 檔中,或使用 %include指令處理整個 h 或 c 檔
  4. 確認語法合於ANSI
  5. 如果不是直接引入 h 檔,請確認宣告的型態順序正確,以使介面可以順利編譯
  6. 將main()函數改名(但函式庫中應該不會有這個函數)
  7. 執行swig並編譯
官方文件在 swig-2.0.8/Doc/Manual/Perl5.html#Perl5_nn3 ,31.2節首先說明最簡單的情況,i 檔被 swig 編譯後會產生 c 檔(包含 i 檔中對應的宣告,應在此檔提供定義)及 pm 檔(包含載入模組的 perl 程式),要建置模組就必需將 c 檔編譯並連結到程式(我想它說的是31.2.2~4節所言,連結到perl);linking 有兩種,一種是動態,一種是靜態(不建議);31.2.2及31.2.3講的是編譯動態連結程式庫,前者使用gcc(不建議),後者使用Makemaker(建議使用)。31.2.2看一下可以了解連結的基礎,概念和一般win平台上dll的編譯其實是一樣的,要注意shared object 的名稱需同於module,並且至少要用gcc編譯swig產生的 *_wrap.c 檔;31.2.3則稍微說明一下Makemaker的用法,注意這裏提供的參數與上節的對應,另外在 http://gdwang.blogspot.tw/2011/09/linux-how-to-write-perl-extension-use.html 有給出比較實際的語法,而且所連結的成員通常是會包含程式庫沒錯,步驟上就是呼叫swig,用gcc編譯swig產生的 *_wrap.c 檔,寫Makefile.PL,執行perl Makerfile.PL,make,make install。31.2.5後半講到連結so的可能問題,算是這個架構的收尾。

沒有留言:

張貼留言