Поделиться через


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

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

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