represent_as 属性
利用 [represent_as] 属性,可以指定如何将特定的可传输数据类型表示给应用程序。 为此,可以指定已知可传输类型的表示类型的名称并提供转换例程。 还必须提供例程来释放数据类型对象使用的内存。
使用 [represent_as] 属性来呈现具有不同(可能不可传输)数据类型的应用程序,而不是客户端和服务器之间实际传输的类型。 在 MIDL 编译时,应用程序作的类型也可能未知。 选择定义完善的可传输类型时,无需关注异类环境中的数据表示形式。 [represent_as] 属性可以减少通过网络传输的数据量,使应用程序更高效。
[represent_as] 属性类似于 [transmit_as] 属性。 但是,虽然 [transmit_as] 允许指定将用于传输的数据类型,[represent_as] 可用于指定应用程序的数据类型表示方式。 在 MIDL 处理的文件中不需要定义表示的类型;可以在使用 C 编译器编译存根时定义它。 为此,请使用 应用程序配置文件 (ACF) 中的 include 指令编译相应的头文件。 例如,对于可传输类型 named_type,以下 ACF 为应用程序定义本地类型 repr_type:
typedef [represent_as(repr_type) [, type_attribute_list] named_type;
下表描述了四个程序员提供的例程。
常规 | 描述 |
---|---|
named_type_from_local | 分配网络类型的实例,并将本地类型转换为网络类型。 |
named_type_to_local | 从网络类型转换为本地类型。 |
named_type_free_local | 释放由调用 named_type_to_local 例程(而不是类型本身)分配的内存。 |
named_type_free_inst | 释放网络类型的存储(双方)。 |
除了这四个程序员提供的例程之外,命名类型不会由应用程序作。 应用程序可见的唯一类型是表示的类型。 应用程序使用表示的类型名称,而不是编译器生成的原型和存根中的传输类型名称。 必须为双方提供一组例程。
对于临时 named_type 对象,存根将调用 named_type_free_inst 释放调用 named_type_from_local分配的任何内存。
如果表示的类型是指针或包含指针,则 named_type_to_local 例程必须为指针指向的数据分配内存(表示的类型对象本身由通常的存根作)。 对于 [out] 和 [中的 [] 参数,包含 [represent_as或其组件之一)的类型,会自动为包含该属性的数据对象调用 named_type_free_local 例程。 对于 [in] 参数,仅当 [represent_as] 属性应用于参数时,才会调用 named_type_free_local 例程。 如果特性已应用于参数的组件,则不会调用 *_free_local 例程。 对于仅 [in] 参数,不为嵌入数据调用和最多调用一次(与顶级属性相关)调用例程。
注意
可以将 [transmit_as] 和 [represent_as] 属性应用于同一类型。 封送数据时,先应用 [represent_as] 类型转换,然后应用 [transmit_as] 转换。 取消划界数据时,将反转顺序。 因此,封送时, *_from_local 分配命名类型的实例,并将其从本地类型对象转换为临时命名类型对象。 此对象是用于 *_to_xmit 例程的呈现类型对象。 然后,*_to_xmit 例程分配传输的类型对象,并将其从呈现的对象(命名)对象转换为传输的对象。
长整数数组可用于表示链接列表。 这样,应用程序将作列表,传输在传输此类型的列表时使用长整数数组。 可以从数组开始,但使用具有开放式整数数组的构造更方便。 以下示例演示如何执行此作。
/* IDL definitions */
typedef struct_lbox
{
long data;
struct_lbox * pNext;
} LOC_BOX, * PLOC_BOX;
/* The definition of the local type visible to the application,
as shown above, can be omitted in the IDL file. See the include
in the ACF file. */
typedef struct_xmit_lbox
{
short Size;
[size_is(Size)] long DaraArr[];
} LONGARR;
void WireTheList( [in,out] LONGARR * pData );
/* ACF definitions */
/* If the IDL file does not have a definition for PLOC_BOX, you
can still ready it for C compilation with the following include
statement (notice that this is not a C include):
include "local.h";*/
typedef [represent_as(PLOC_BOX)] LONGARR;
请注意,使用 LONGARR 类型的例程的原型实际上显示在 Stub.h 文件中,作为 PLOC_BOX 代替 LONGARR 类型的。 Stub_c.c 文件中的相应存根也是如此。
必须提供以下四个函数:
void __RPC_USER
LONGARR_from_local(
PLOC_BOX __RPC_FAR * pList,
LONGARR __RPC_FAR * _RPC_FAR * ppDataArr );
void __RPC_USER
LONGARR_to_local(
LONGARR __RPC_FAR * _RPC_FAR * ppDataArr,
PLOC_BOX __RPC_FAR * pList );
void __RPC_USER
LONGARR_free_inst(
LONGARR __RPC_FAR * pDataArr);
void __RPC_USER
LONGARR_free_local(
PLOC_BOX __RPC_FAR * pList );
上面所示的例程执行以下作:
- LONGARR_from_local 例程对列表的节点进行计数,分配一个 LONGARR 对象,其大小 为(LONGARR) + Count*sizeof(long),将 Size 字段设置为 Count,并将数据复制到 DataArr 字段。
- LONGARR_to_local 例程创建一个包含 Size 节点的列表,并将数组传输到相应的节点。
- 在这种情况下,LONGARR_free_inst 例程不释放任何内容。
- LONGARR_free_local 例程释放列表的所有节点。