シリアル化サービスの使用
MIDL は、属性 [encode] と [decode] を使用して、プロシージャのシリアル化スタブを生成します。 このルーチンを呼び出すときは、リモート呼び出しではなくシリアル化呼び出しを実行します。 プロシージャ引数は、通常の方法でバッファーにマーシャリングされるか、バッファーからマーシャリング解除されます。 その後、バッファーを完全に制御できます。
これに対し、プログラムで型のシリアル化を実行すると (型にシリアル化属性のラベルが付けられます)、MIDL は、その型のオブジェクトのサイズ、エンコード、デコードを行うルーチンを生成します。 データをシリアル化するには、適切な方法でこれらのルーチンを呼び出す必要があります。 型のシリアル化は Microsoft 拡張機能であるため、DCE 互換 (/osf) モードでコンパイルする場合は使用できません。 [encode] 属性と [decode] 属性をインターフェイス属性として使用することで、RPC は IDL ファイルで定義されているすべての型とルーチンにエンコードを適用します。
シリアル化サービスを使用する場合は、適切に調整されたバッファーを指定する必要があります。 バッファーの先頭は、8 の倍数または 8 バイトのアラインされたアドレスに配置する必要があります。 プロシージャのシリアル化の場合、各プロシージャ呼び出しは、8 バイトアラインされたバッファー位置にマーシャリングするか、マーシャリング解除する必要があります。 型のシリアル化、サイズ変更、エンコード、デコードの場合は、8 バイトの位置で開始する必要があります。
アプリケーションでバッファーが確実にアラインされるようにする方法の 1 つは、アラインされたバッファーを作成するように midl_user_allocate 関数を記述することです。 次のコード サンプルは、これを行う方法を示しています。
#include <windows.h>
#define ALIGN_TO8(p) (char *)((unsigned long)((char *)p + 7) & ~7)
void __RPC_FAR *__RPC_USER MIDL_user_allocate(size_t sizeInBytes)
{
unsigned char *pcAllocated;
unsigned char *pcUserPtr;
pcAllocated = (unsigned char *) malloc( sizeInBytes + 15 );
pcUserPtr = ALIGN_TO8( pcAllocated );
if ( pcUserPtr == pcAllocated )
pcUserPtr = pcAllocated + 8;
*(pcUserPtr - 1) = pcUserPtr - pcAllocated;
return( pcUserPtr );
}
次の例は、対応する midl_user_free関数を 示しています。
void __RPC_USER MIDL_user_free(void __RPC_FAR *f)
{
unsigned char * pcAllocated;
unsigned char * pcUserPtr;
pcUserPtr = (unsigned char *) f;
pcAllocated = pcUserPtr - *(pcUserPtr - 1);
free( pcAllocated );
}