Использование служб сериализации
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 );
}