Составители:
Рубрика:
токенов, который соответствует типам, объявленным в сборке
(другими словами, получаем содержимое таблицы TypeDef):
mdTypeDef tmp;
mdTypeDef *tokens;
HCORENUM Enum = 0;
unsigned long tokenCount;
mdimp->EnumTypeDefs(&Enum,&tmp,1,&tokenCount);
mdimp->CountEnum(Enum,&tokenCount);
if (tokenCount > 0)
{
tokens = new mdTypeDef [tokenCount];
tokens[0] = tmp;
if (tokenCount > 1)
mdimp->EnumTypeDefs(
&Enum,tokens+1,tokenCount-1,
&tokenCount
);
mdimp->CloseEnum(Enum);
}
Первый вызов метода EnumTypeDefs создает дескриптор массива
токенов (он записывается в переменную Enum), а также возвра-
щает первый элемент этого массива (он сохраняется в перемен-
ной tmp).
Затем метод CountEnum записывает в переменную tokenCount раз-
мер массива токенов, после чего выделяется нужное количество
памяти (для массива tokens) и второй раз вызывается метод
EnumTypeDefs. Обратите внимание, что первому элементу масси-
ва tokens мы присваиваем значение переменной tmp.
2. Методы FindXXX предназначены для поиска элементов метадан-
ных, удовлетворяющих некоторым критериям. Например, поиск
типа по его имени («MyType1») проводится следующим образом:
mdTypeDef token;
mdimp->FindTypeByName(L”MyType1”,NULL,&token);
3. Методы GetXXX используются для получения свойств элементов
метаданных. Например, получение содержимого строки, токен
которой хранится в переменной strToken, выглядит так:
unsigned short s[1024];
unsigned long len;
mdimp->GetUserString(strToken,s,1024,&len);
Обратите внимание, что для хранения одного символа применяется
тип unsigned short. Причина в том, что для представления строко-
вых данных в .NET используется 16-разрядная кодировка Unicode.
Анализ кода на CIL
155
Работа с Metadata Unmanaged API начинается с инициализации сис-
темы COM и получения указателя на интерфейс IMetadataDispenserEx:
CoInitialize(NULL);
IMetaDataDispenser *dispenser;
HRESULT h = CoCreateInstance(
CLSID_CorMetaDataDispenser,
NULL,
CLSCTX_INPROC_SERVER,
IID_IMetaDataDispenserEx,
(void **)&dispenser
);
if (h)
printf(“Error”);
Затем можно с помощью метода OpenScope этого интерфейса загру-
зить существующую сборку в память или с помощью метода DefineScope
создать новую сборку. Оба метода возвращают указатель на интерфейс, че-
рез который можно в дальнейшем осуществлять чтение или генерацию
метаданных. В следующем фрагменте программы происходит вызов мето-
да OpenScope для чтения метаданных из сборки test.exe:
IMetaDataImport *mdimp;
HRESULT h = dispenser->OpenScope(
L”test.exe”,
0,
IID_IMetaDataImport,
(IUnknown**)&mdimp
);
if (h)
printf(“Error”);
При завершении работы с Metadata Unmanaged API необходимо ос-
вободить указатели на полученные интерфейсы:
mdimp->Release();
dispenser->Release();
Чтение метаданных из сборки осуществляется через методы интер-
фейса IMetadataImport, которые условно можно разделить на три основ-
ные группы:
1. Методы EnumXXX возвращают массивы токенов, описывающих
определенную категорию элементов метаданных. Ответствен-
ность за выделение достаточного количества памяти для хране-
ния возвращаемого массива токенов лежит на программисте,
использующем библиотеку, а так как количество токенов зара-
нее неизвестно, то приходится использовать прием, проиллюст-
рированный следующим примером. В нем мы получаем массив
154
CIL и системное программирование в Microsoft .NET
154 CIL и системное программирование в Microsoft .NET Анализ кода на CIL 155
Работа с Metadata Unmanaged API начинается с инициализации сис- токенов, который соответствует типам, объявленным в сборке
темы COM и получения указателя на интерфейс IMetadataDispenserEx: (другими словами, получаем содержимое таблицы TypeDef):
CoInitialize(NULL); mdTypeDef tmp;
IMetaDataDispenser *dispenser; mdTypeDef *tokens;
HRESULT h = CoCreateInstance( HCORENUM Enum = 0;
CLSID_CorMetaDataDispenser, unsigned long tokenCount;
NULL, mdimp->EnumTypeDefs(&Enum,&tmp,1,&tokenCount);
CLSCTX_INPROC_SERVER, mdimp->CountEnum(Enum,&tokenCount);
IID_IMetaDataDispenserEx, if (tokenCount > 0)
(void **)&dispenser {
); tokens = new mdTypeDef [tokenCount];
if (h) tokens[0] = tmp;
printf(“Error”); if (tokenCount > 1)
Затем можно с помощью метода OpenScope этого интерфейса загру- mdimp->EnumTypeDefs(
зить существующую сборку в память или с помощью метода DefineScope &Enum,tokens+1,tokenCount-1,
создать новую сборку. Оба метода возвращают указатель на интерфейс, че- &tokenCount
рез который можно в дальнейшем осуществлять чтение или генерацию );
метаданных. В следующем фрагменте программы происходит вызов мето- mdimp->CloseEnum(Enum);
да OpenScope для чтения метаданных из сборки test.exe: }
IMetaDataImport *mdimp; Первый вызов метода EnumTypeDefs создает дескриптор массива
HRESULT h = dispenser->OpenScope( токенов (он записывается в переменную Enum), а также возвра-
L”test.exe”, щает первый элемент этого массива (он сохраняется в перемен-
0, ной tmp).
IID_IMetaDataImport, Затем метод CountEnum записывает в переменную tokenCount раз-
(IUnknown**)&mdimp мер массива токенов, после чего выделяется нужное количество
); памяти (для массива tokens) и второй раз вызывается метод
if (h) EnumTypeDefs. Обратите внимание, что первому элементу масси-
printf(“Error”); ва tokens мы присваиваем значение переменной tmp.
При завершении работы с Metadata Unmanaged API необходимо ос- 2. Методы FindXXX предназначены для поиска элементов метадан-
вободить указатели на полученные интерфейсы: ных, удовлетворяющих некоторым критериям. Например, поиск
mdimp->Release(); типа по его имени («MyType1») проводится следующим образом:
dispenser->Release(); mdTypeDef token;
Чтение метаданных из сборки осуществляется через методы интер- mdimp->FindTypeByName(L”MyType1”,NULL,&token);
фейса IMetadataImport, которые условно можно разделить на три основ- 3. Методы GetXXX используются для получения свойств элементов
ные группы: метаданных. Например, получение содержимого строки, токен
1. Методы EnumXXX возвращают массивы токенов, описывающих которой хранится в переменной strToken, выглядит так:
определенную категорию элементов метаданных. Ответствен- unsigned short s[1024];
ность за выделение достаточного количества памяти для хране- unsigned long len;
ния возвращаемого массива токенов лежит на программисте, mdimp->GetUserString(strToken,s,1024,&len);
использующем библиотеку, а так как количество токенов зара- Обратите внимание, что для хранения одного символа применяется
нее неизвестно, то приходится использовать прием, проиллюст- тип unsigned short. Причина в том, что для представления строко-
рированный следующим примером. В нем мы получаем массив вых данных в .NET используется 16-разрядная кодировка Unicode.
Страницы
- « первая
- ‹ предыдущая
- …
- 82
- 83
- 84
- 85
- 86
- …
- следующая ›
- последняя »
