シリアル化サービスの使用

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 );
}