C の構造体を扱うときには、XS の型に `T_PTROBJ' か `T_PRTREF' 
を選択する必要があります。どちらの型も複雑なオブジェクトへのポインタを扱
うように設計されています。T_PTRREF 型では、Perl のオブジェクトが 
bless されていなくてもよいが、T_PTROBJ 型では、オブジェクトが 
bless されていなければなりません。T_PTROBJ を使うことで、XSUB は 
Perl オブジェクトが期待する型であることを確認するようになりますから、型
チェックを行なうことができます。
次の XS コードでは、 getnetconfigent() 関数を ONC TIRPC といっしょ
に使っています。 getnetconfigent() 関数は、C の構造体へのポインタ
を返すもので、以下のプロトタイプで示されるものです。この例では、C のポイ
ンタを Perl のリファレンスにする方法を示すことにします。Perl は、このリ
ファレンスを bless されたオブジェクトへのポインタとみなして、このオブジェ
クトに対してデストラクタを起動しようとします。デストラクタは、
getnetconfigent() が使ったメモリを解放するために、XS ソース内で記
述しす。XS でのデストラクタは、DESTROY で終わる名前を持つ XSUB 関数を記
述することで作ることができます。XS デストラクタは、別の XSUB が 
malloc したメモリを、 free するために使うことができます。
struct netconfig *getnetconfigent(const char *netid);
struct netconfig のために typedef を行なっています。Perlの
オブジェクトは、C での型の名前に Ptr というタグを付けたものにマッ
チする名前のクラスで bless され、その名前は、Perl のパッケージ名
として使われるときには、空白を入れません。デストラクタは、そのオブジェク
トの属するクラスに対応するクラスに置かれ、Perl 側では DESTROY と
いう名前で参照されますので、PREFIX キーワードを使用して関数名の先
頭部分をみないようにします。
typedef struct netconfig Netconfig;
MODULE = RPC  PACKAGE = RPC
Netconfig *
getnetconfigent(netid)
     char *  netid
MODULE = RPC  PACKAGE = NetconfigPtr  PREFIX = rpcb_
void
rpcb_DESTROY(netconf)
     Netconfig *  netconf
     CODE:
     printf("Now in NetconfigPtr::DESTROY\n");
     free( netconf );
この例には、次のような typemap のエントリが必要になります。
拡張に際して、新しい typemap を設けるときには、 @xref{typemap}, の節
の情報も参考にしてください。
TYPEMAP Netconfig * T_PTROBJ
今回の例は、
use RPC;
$netconf = getnetconfigent("udp");
という Perl の文で使用されます。
Perl は $netconf で参照されるオブジェクトを消去するとき、そのオブ
ジェクトを用意された XSUB DESTROY 関数に送ります。Perl では、このオブジェ
クトが C の構造体であって、Perl のオブジェクトではないと知るすべがありま
せんし、関与もしません。この意味で、 getnetconfigent() XSUB で作
られたオブジェクトと、普通の Perl のサブルーティンで作られたオブジェクト
の区別はありません。
Go to the first, previous, next, last section, table of contents.