● fixed X ユーティリティー
FIXEDVAL値の配列
ローカル、またはグローバルで FIXEDVAL値の一次元配列を確保する場合は、大体が次のような形になると思います。
例1.
#define SIZE 数値幅
#define CNT 要素数
FIXEDVAL val[CNT][SIZE];
多くの変数を処理しなければならない場合は、都合の良い形です。
このようにして確保した変数は、次のようにインデックスで参照する事ができます。
int i;
for(i = 0;i < CNT;i++) /* 全ての要素をゼロクリア */
memset(val[i],0,SIZE);
また、領域はメモリ上で連続していますので、メモリクリア等の処理は
memset(val,0,CNT * SIZE); /* 全ての要素をゼロクリア */
と、まとめて処理する事もできます。

例1 は二次元配列で FIXEDVAL値の一次元配列を確保していますが、次のようにポインタのテーブルを使用する方法もあります。
例2.
FIXEDVAL val1[SIZE],val2[SIZE],val3[SIZE],val4[SIZE],val5[SIZE];
PFIXEDVAL tbl[CNT];
tbl[0] = val1; tbl[1] = val2; tbl[2] = val3; tbl[3] = val4; tbl[4] = val5;
メモリのアドレスを格納するテーブルと実体を分けて確保し、後にテーブルへアドレスを格納し、関連付けます。
面倒な方法ではありますが、実体を直接いじらずに位置の移動を行う事ができる利点があります(ポインタテーブルの中身を入れ替えるだけで良い)。

ユーティリティー関数で配列を作成する
例1 の方法はC/C++の機能だけで十分対応可能です。ユーティリティーでは、作成が面倒な例2 についての関数が用意されています。
例3.
#include <stdlib.h>
#include "fixedX.h"
#include "fixutil.h"
/* メモリ確保関数 */
void * __stdcall user_alloc(size_t size,void *param)
{
/*
ここでは malloc を使用していますが、C++の new や
Windows API のメモリ関数を使用する事もできます。
*/
return malloc(size);
}
/* メモリ解放関数 */
void __stdcall user_free(void *pbase,void *param)
{
/*
使用しているメモリ確保関数と対になる解放関数を
使用する必要があります。
malloc や calloc の場合は free
new の場合は delete
GlobalAlloc の場合は GlobalFree
etc.
*/
free(pbase);
}
#include <stdio.h>
#define BIT 32
#define SIZE (BIT/8)
#define CNT 5
void main(void )
{
MEMTABLEINFO mi;
MEMFUNC mf;
FIXEDVAL work[SIZE];
PFIXEDVAL *pptr;
char buf[256];
int ret,i;
/* FIXEDVAL型の一次元配列を作成する */
mi.width = SIZE; /* 1 要素の数値幅 */
mi.cnt = CNT; /* 配列の要素数 */
mf.pfmemalloc = user_alloc; /* メモリ確保関数のポインタ */
if ((ret = fixedutil_alloc_memtable(&mi,&mf)) != STATUS_NORMAL){
printf("エラー:%s\n",fixedutil_errormes(ret));
return;
}
/* 配列に対しての処理を行う */
for(i = 0;i < CNT;i++)
fixedutil_setulval32(mi.ppmem[i],SIZE,i + 20);
/*
0 : 20
1 : 21
2 : 22
3 : 23
4 : 24
*/
pptr = mi.ppmem;
for(i = 0;i < mi.cnt;i++){
fixedutil_unsigned_num2str(*pptr++,SIZE,10,buf,work);
printf("%d : %s\n",i,buf);
}
/* 配列の解放 */
mf.pfmemfree = user_free; /* メモリ解放関数のポインタ */
fixedutil_free_memtable(&mi,&mf);
}
一次元配列の確保は、関数fixedutil_alloc_memtable で行います。MEMTABLEINFO構造体の実体に配列要素数と数値幅をセットし、MEMFUNC構造体の実体にはメモリ確保・解放関数のポインタをセットします。
確保した一次元配列は、MEMTABLEINFO構造体のメンバ ppmem から、自由にアクセスする事ができます。
ユーティリティーでは、メモリを確保する処理をコールバックの形で呼び出し側に依頼しています。呼び出し側は例3 のようにメモリ確保のコールバック関数を用意しなければなりませんが、次のような利点があります。
- 幾つかあるメモリ確保・解放処理を呼び出し側が選べる
- メモリ確保・解放関数の所属・種類を統一する事ができる
(通常、メモリ確保・解放処理は、同じライブラリに属するもの・同じ処理系で行わなければならない)
- 必要なら、ユーザ独自のメモリ管理処理を行う事もできる
配列を解放する場合は、fixedutil_alloc_memtable と同じ引数で関数fixedutil_free_memtable を呼び出します。引数は同じですが、設定するメンバが若干異なる事には注意してください。