Использование служб сериализации

MIDL создает заглушку сериализации для процедуры с атрибутами [encode] и [decode]. При вызове этой подпрограммы вместо удаленного вызова выполняется вызов сериализации. Аргументы процедуры маршалируются в буфер или удаляются из буфера обычным способом. После этого вы можете полностью контролировать буферы.

В отличие от этого, когда программа выполняет сериализацию типа (тип помечен атрибутами сериализации), MIDL создает подпрограммы для изменения размера, кодирования и декодирования объектов этого типа. Чтобы сериализовать данные, необходимо вызывать эти подпрограммы соответствующим образом. Сериализация типов является расширением Майкрософт и поэтому недоступна при компиляции в режиме совместимости 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 );
}