XSLoader - 動態載入 C 函式庫至 Perl 程式碼
版本 0.32
package YourPackage;
require XSLoader;
XSLoader::load(__PACKAGE__, $VERSION);
此模組定義一個標準的簡化介面,用於許多平台上可用的動態連結機制。其主要目的是實作 Perl 模組的便宜自動動態載入。
如需更複雜的介面,請參閱 DynaLoader。DynaLoader
的許多(大部分)功能未在 XSLoader
中實作,例如 dl_load_flags
,XSLoader
不會遵守。
DynaLoader
遷移使用 DynaLoader 的典型模組會像這樣開始
package YourPackage;
require DynaLoader;
our @ISA = qw( OnePackage OtherPackage DynaLoader );
our $VERSION = '0.01';
__PACKAGE__->bootstrap($VERSION);
變更為
package YourPackage;
use XSLoader;
our @ISA = qw( OnePackage OtherPackage );
our $VERSION = '0.01';
XSLoader::load(__PACKAGE__, $VERSION);
換句話說:將 require DynaLoader
替換為 use XSLoader
,從 @ISA
中移除 DynaLoader
,將 bootstrap
變更為 XSLoader::load
。別忘了在 XSLoader::load
行上加上套件名稱的引號,並在引數(上方的 $VERSION
)之前加上逗號(,
)。
當然,如果 @ISA
中只包含 DynaLoader
,則根本不需要 @ISA
指定;此外,如果使用更向後相容的
use vars qw($VERSION @ISA);
則可以將此對 @ISA
的參照與 @ISA
指定一起移除。
如果在 bootstrap
行上未指定 $VERSION
,最後一行會變成
XSLoader::load(__PACKAGE__);
在這種情況下,可以進一步簡化為
XSLoader::load();
因為 load
會使用 caller
來判斷套件。
如果您想要兩全其美,則需要更複雜的樣板。
package YourPackage;
our @ISA = qw( OnePackage OtherPackage );
our $VERSION = '0.01';
eval {
require XSLoader;
XSLoader::load(__PACKAGE__, $VERSION);
1;
} or do {
require DynaLoader;
push @ISA, 'DynaLoader';
__PACKAGE__->bootstrap($VERSION);
};
由於我們將 use XSLoader
替換為 require
,因此需要加上 XSLoader::load()
引數的括號,所以編譯器不知道存在 XSLoader::load()
函式。
此樣板使用低開銷的 XSLoader
(如果存在);如果與沒有 XSLoader
的舊版 Perl 一起使用,它會改用 DynaLoader
。
如果 XSUB 函式只會從其他模組呼叫,請略過此部分;只有當您從模組中的程式碼呼叫 XSUB,或在 XS 檔案中有 BOOT:
區段(請參閱 perlxs 中的 "The BOOT: Keyword")時才閱讀。這裡描述的內容同樣適用於 DynaLoader 介面。
使用 XS 的足夠複雜的模組將同時具有 Perl 程式碼(定義在 YourPackage.pm 中)和 XS 程式碼(定義在 YourPackage.xs 中)。如果此 Perl 程式碼呼叫此 XS 程式碼,和/或此 XS 程式碼呼叫 Perl 程式碼,則應注意初始化順序。
呼叫 XSLoader::load()
(或 bootstrap()
)會呼叫模組的 bootstrap 程式碼。對於由 xsubpp 建置的模組(幾乎所有模組),這會有三個副作用
執行健全性檢查,以確保 .pm 和(已編譯的).xs 部分的版本相容。如果指定了 $VERSION
,則會使用它來進行檢查。如果未指定,則預設為 $XS_VERSION // $VERSION
(在模組的命名空間中)
XSUB 可從 Perl 存取
如果 .xs 檔案中有 BOOT:
區段,則會呼叫該處的程式碼。
因此,如果 .pm 檔案中的程式碼呼叫這些 XSUB,則在定義 Perl 程式碼之前安裝 XSUB 會很方便;例如,這會讓 XSUB 的原型對此 Perl 程式碼可見。或者,如果 BOOT:
區段呼叫 .pm 檔案中定義的 Perl 函式(或使用 Perl 變數),則必須在呼叫 XSLoader::load()
(或 bootstrap()
)之前定義這些函式或變數。
第一種情況更為常見,因此將樣板重寫為
package YourPackage;
use XSLoader;
our ($VERSION, @ISA);
BEGIN {
@ISA = qw( OnePackage OtherPackage );
$VERSION = '0.01';
# Put Perl code used in the BOOT: section here
XSLoader::load(__PACKAGE__, $VERSION);
}
# Put Perl code making calls into XSUBs here
如果 BOOT:
區段和 Perl 程式碼的相互依賴性比這更複雜(例如,BOOT:
區段呼叫 Perl 函式,而 Perl 函式又呼叫具有原型的 XSUB),則完全移除 BOOT:
區段。用函式 onBOOT()
取代它,並像這樣呼叫它
package YourPackage;
use XSLoader;
our ($VERSION, @ISA);
BEGIN {
@ISA = qw( OnePackage OtherPackage );
$VERSION = '0.01';
XSLoader::load(__PACKAGE__, $VERSION);
}
# Put Perl code used in onBOOT() function here; calls to XSUBs are
# prototype-checked.
onBOOT;
# Put Perl initialization code assuming that XS is initialized here
找不到 %s 符號在 %s 中
(F) 在擴充模組中找不到引導符號。
無法為模組 %s 載入 %s:%s
(F) 擴充模組的載入或初始化失敗。詳細錯誤如下。
載入 %s 後存在未定義的符號:%s
(W) 如訊息所述,儘管擴充模組已正確載入和初始化,但仍有一些符號保持未定義。未定義符號清單如下。
為了盡可能減少開銷,只檢查一個可能的位置以找到擴充 DLL(此位置是 make install
會放置 DLL 的位置)。如果找不到,則會將 DLL 的搜尋透明委派給 DynaLoader
,它會沿著 @INC
清單尋找 DLL。
特別是,這適用於用於測試尚未安裝的擴充的 @INC
結構。這表示執行已解除安裝的擴充可能比在 make install
之後執行相同的擴充開銷更大。
以不帶任何引數呼叫 XSLoader::load()
的新簡化方式在 Perl 5.8.4 和 5.8.5 上無法使用。
請透過 perlbug(1) 工具回報任何錯誤或功能要求。
Ilya Zakharevich 最初從 DynaLoader
中萃取出 XSLoader
。
CPAN 版本目前由 Sébastien Aperghis-Tramoni <sebastien@aperghis.net> 維護。
前一位維護者是 Michael G Schwern <schwern@pobox.com>。
版權所有 (C) 1990-2011 Larry Wall 等人。
此程式為自由軟體;您可以在與 Perl 相同的條款下重新散布或修改它。