まだまだ改良の余地がありますが暫定的なものとして公開します。
define(`defObject',` setIndexer($2) $1 $2=NULL; $2=$1Init(shift($@)); '); define(`setIndexer',`define(`$1', `if'`else(' `$'`#'`,2,' ``$1''`->a['`$'`1'`*'`$'`2'`], ``$1''' `)' ) '); #include <stdlib.h> typedef struct{ int *a; } testObj; testObj *testObjInit(void *a,int n){ struct testObj *result=malloc(sizeof(struct testObj)); result->a=malloc(sizeof(int)*n); return result; } int main(void){ defObject(testObj,objs,1024); //① objs(1,3)+=1;//ここでインデクサのようなアクセスを実現している objs->a[2]=2;//普通にアクセスすることも出来る }①のdefObjectの第1引数は型名、第2引数は宣言する変数名です。
第3引数以降はtestObjInitに渡すデータです。
defObjectの中で[構造体名]Init関数を呼び出しています。(ここではtestObjInit)
defObjectの中で呼び出されているsetIndexerマクロがインデクサを実現する機能になります。
setIndexerの中の ``$1''`->a['`$'`1'`*'`$'`2'`], はobjs(1,3)と呼び出されたとき、objs->a[1*3]に置換することを書いています。
仮にsetIndexerを次のように書いた場合、
define(`setIndexer',`define(`$1', `if'`else(' `$'`#'`,1,' ``$1''`->a['`$'`1'], ``$1''' `)' ) ');objs(3)がobjs->a[3]に置換されます.