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