次の方法で共有


transmit_as属性

[transmit_as] 属性を使用すると、低レベルでデータをマーシャリングすることを心配することなく、つまり異種環境でのデータ サイズやバイト スワップを気にすることなく、データ マーシャリングを制御できます。 [ transmit_as] 属性を使用すると、ネットワーク経由で送信されるデータの量を減らすことで、アプリケーションの効率を高めることができます。

[transmit_as] 属性を使用して、アプリケーションによって提供されるデータ型を使用する代わりに、RPC スタブがネットワーク経由で送信するデータ型を指定します。 データ型を転送に使用する型との間で変換するルーチンを指定します。 また、データ型と転送される型に使用されるメモリを解放するルーチンも指定する必要があります。 たとえば、次の例では 、xmit_type を、 type_spec型として指定されたすべてのアプリケーション データに対して送信されるデータ型として定義します。

typedef [transmit_as (xmit_type)] type_spec type;

次の表では、プログラマが提供する 4 つのルーチン名について説明します。 Type はアプリケーションで認識されるデータ型であり、 xmit_type は転送に使用されるデータ型です。

ルーチンによって返される値 説明
type_to_xmit 送信された型のオブジェクトを割り当て、アプリケーションの種類からネットワーク経由で送信される型 (呼び出し元と呼ばれるオブジェクト) に変換します。
Type_from_xmit 送信された型からアプリケーションの種類 (呼び出し元と呼び出されたオブジェクト) に変換します。
Type_free_inst アプリケーションの種類で使用されるリソースを解放します (オブジェクトのみと呼ばれます)。
Type_free_xmit type*_*to_xmit ルーチン (呼び出し元と呼び出されたオブジェクト) によって返されるストレージを解放します。

 

これら 4 つのプログラマが提供する関数以外では、送信される型はアプリケーションによって操作されません。 転送される種類は、ネットワーク経由でデータを移動するためにのみ定義されます。 データがアプリケーションで使用される型に変換されると、送信された型で使用されるメモリが解放されます。

これらのプログラマが提供するルーチンは、方向属性に基づいて、クライアントまたはサーバー アプリケーションによって提供されます。 パラメーターが [in] のみの場合、クライアントはサーバーに送信します。 クライアントには、 type_to_xmit 関数と type_free_xmit関数が 必要です。 サーバーには、 type_from_xmitとtype_free_inst の機能 必要です。 [出力] のみのパラメーターの場合、サーバーはクライアントに送信します。 サーバー アプリケーションは 、type_to_xmit 関数と type_free_xmit関数を 実装する必要があります。一方、クライアント プログラムは 、type_from_xmit 関数を提供する必要があります。 一時的 なxmit_type オブジェクトの場合、スタブは type*_*free_xmit を呼び出して、 type_to_xmitの呼び出しによって割り当てられたメモリを解放します。

特定のガイドラインは、アプリケーションの種類のインスタンスに適用されます。 アプリケーションの型がポインターであるか、ポインターが含まれている場合、 type_from_xmit ルーチンは、ポインターが指すデータのメモリを割り当てる必要があります (アプリケーション型オブジェクト自体は、通常の方法でスタブによって操作されます)。

[transmit_as] 属性を含む型の [out] パラメーターと [in, out] out パラメーター、またはそのコンポーネントの 1 つの場合、type_free_inst ルーチンは、 属性を持つデータ オブジェクトに対して自動的に呼び出されます。 in パラメーターの場合、type_free_inst ルーチンは、パラメーターに [transmit_as] 属性が適用されている場合にのみ呼び出されます。 属性が パラメーターのコンポーネントに適用されている場合、 type_free_inst ルーチンは呼び出されません。 埋め込みデータの解放呼び出しと、 in パラメーターの 最大 1 回の呼び出し (最上位レベルの属性に関連) はありません。

MIDL 2.0 では、クライアントとサーバーの両方で 4 つの関数をすべて提供する必要があります。 たとえば、リンクリストはサイズの大きな配列として送信できます。 type_to_xmit ルーチンは、リンクリストをウォークし、順序付けられたデータを配列にコピーします。 配列要素は、リスト構造に関連付けられている多くのポインターを送信する必要がないように並べ替えられています。 type_from_xmit ルーチンは、配列を読み取り、その要素をリンク リスト構造に配置します。

二重リンク リスト (DOUBLE_LINK_LIST) には、前のリスト要素と次のリスト要素へのデータとポインターが含まれます。

typedef struct _DOUBLE_LINK_LIST 
{
    short sNumber;
    struct _DOUBLE_LINK_LIST * pNext;
    struct _DOUBLE_LINK_LIST * pPrevious;
} DOUBLE_LINK_LIST;

[transmit_as]属性は、複雑な構造を出荷するのではなく、ネットワーク経由で配列として送信するために使用できます。 配列内の項目のシーケンスは、リスト内の要素の順序を低コストで保持します。

typedef struct _DOUBLE_XMIT_TYPE 
{
    short sSize;
    [size_is(sSize)] short asNumber[];
} DOUBLE_XMIT_TYPE;

[transmit_as] 属性が IDL ファイルに表示されます。

typedef [transmit_as(DOUBLE_XMIT_TYPE)]  DOUBLE_LINK_LIST DOUBLE_LINK_TYPE;

次の例では、 ModifyListProc によって、DOUBLE_LINK_TYPE型のパラメーターが [in, out] パラメーターとして定義されています。

void ModifyListProc([in, out] DOUBLE_LINK_TYPE * pHead)

4 つのプログラマ定義関数は、関数名に型の名前を使用し、必要に応じて、提示された型と送信される型をパラメーター型として使用します。

void __RPC_USER DOUBLE_LINK_TYPE_to_xmit ( 
    DOUBLE_LINK_TYPE __RPC_FAR * pList, 
    DOUBLE_XMIT_TYPE __RPC_FAR * __RPC_FAR * ppArray);

void __RPC_USER DOUBLE_LINK_TYPE_from_xmit ( 
    DOUBLE_XMIT_TYPE __RPC_FAR * pArray,
    DOUBLE_LINK_TYPE __RPC_FAR * pList);

void __RPC_USER DOUBLE_LINK_TYPE_free_inst ( 
    DOUBLE_LINK_TYPE __RPC_FAR * pList);

void __RPC_USER DOUBLE_LINK_TYPE_free_xmit ( 
    DOUBLE_XMIT_TYPE __RPC_FAR * pArray);