使用序列化服务

MIDL 使用属性 [encode] 和 [decode] 为过程生成序列化存根。 调用此例程时,将执行序列化调用而不是远程调用。 过程参数以通常的方式封送到缓冲区或从缓冲区取消封送。 然后,可以完全控制缓冲区。

相反,当程序执行类型序列化 (类型被标记为序列化属性) 时,MIDL 会生成例程来调整、编码和解码该类型的对象。 若要序列化数据,必须以适当的方式调用这些例程。 类型序列化是 Microsoft 扩展,因此,在 DCE 兼容性 (/osf) 模式下编译时不可用。 通过使用 [encode] 和 [decode] 属性作为接口属性,RPC 将编码应用于 IDL 文件中定义的所有类型和例程。

使用序列化服务时,必须提供足够对齐的缓冲区。 缓冲区的开头必须在 8 或 8 字节对齐的倍数的地址对齐。 对于过程序列化,每个过程调用都必须从 8 字节对齐的缓冲区位置封送或取消封送。 对于类型序列化,大小调整、编码和解码必须从 8 字节对齐的位置开始。

应用程序确保其缓冲区对齐的一种方法是编写 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 );
}