FAQ по Visual Basic

Содержание / Разное Поиск

§ 8.2. Использование Type Library

С помощью Type Library можно описать структуры, интерфейсы и импортируемые функции (разумеется, и многое еще, но в данной статье будут рассмотрены только эти наиболее часто употребимые типы).

Описание cтруктуры (User Defined Type) в Type Library позволяет обойти следующие трудности, возникающие в проекте Standard Exe:

  1. Класс не может иметь метод, аргументом или возвращаемым значением которого является UDT.
  2. Невозможно присвоить variant-переменной значение, имеющее тип UDT.

Интерфейсы чаще всего описываются в Type Library для последующего их использования с ключевым словом Implements.

И, наконец, описание импортируемых функций в Type Library дает следующие преимущества:

  1. Можно указывать тип их аргументов не только LPSTR (ansi-строка), но и LPWSTR (wide-строка), что позволяет легко использовать unicode-функции, оканчивающиеся буквой W.
  2. При вызове импортированных таким образом функций не производится обращение к объекту Err, в то время как при обычном описании функции после ее вызова всегда заполняется свойство Err.LastDllError. Поэтому такое импортирование функций используется при написания многопоточного приложения.

Чтобы скомпилировать Type Library, нужно воспользоваться утилитой midl. Файлы с исходным кодом для Type Library обычно имеют расширение idl (interface definition library) или odl (object definition library).

Язык описания Type Library очень похож на Си. Вот пример, который поможет вам написать и свою библиотеку типов:

[
	uuid(384A0C85-B593-4834-B48B-24BB82707973),
	helpstring("My Type Library"),
	version(1.0)
] 
library MyTLB
{  
	importlib("stdole2.tlb");

	typedef [uuid(97F7AAC4-48D5-4E17-854E-E6A8D73D3178), version(1.0)]
	struct MyUDT
	{
		BSTR Name;
		LONG Hash;
	} MyUDT;

	typedef struct SECURITY_ATTRIBUTES {
		long nLength;
		long lpSecurityDescriptor;
		long bInheritHandle;
	} SECURITY_ATTRIBUTES;

	[dllname("kernel32.dll")]
	module Kernel32
	{
		[entry("SetEvent")]
		LONG SetEvent(
			[in] LONG hEvent);

		[entry("CreateEventA"), helpstring("Создание Event'а")]
		LONG CreateEventA(
			[in] LPVOID lpEventAttributes,
			[in] LONG bManualReset,
			[in] LONG bInitialState,
			[in] LPSTR lpName);

		[entry("CreateEventW"), helpstring("Создание Event'а")]
		LONG CreateEventW(
			[in] LPVOID lpEventAttributes,
			[in] LONG bManualReset,
			[in] LONG bInitialState,
			[in] LPWSTR lpName);
	};

	[
		odl,
		uuid(720E80D2-54A3-42f1-947D-7AD8610070A3),
		version(1.0),
		hidden,
		dual,
		nonextensible,
		oleautomation
	]
	interface ICallback : IDispatch {
		[id(0x68030000)]
		HRESULT FileProcessed(
			[in] BSTR FileName,
			[out, retval] VARIANT_BOOL *pBreak);
	};
};

Все GUID'ы должны быть разными. Можно воспользоваться утилитой guidgen для их генерации.

Итак, в этой библиотеке типов описаны структура SECURITY_ATTRIBUTES, две версии функции CreateEvent и интерфейс ICallback.

Таблица соответствий типов:

Тип VBЭквиватент в idl
Integer SHORT
Long LONG
Single FLOAT
Double DOUBLE
Byte BYTE
Boolean VARIANT_BOOL
String BSTR
Variant VARIANT
Date DATE
Currency CURRENCY
Object IDispatch *

Аргументы, которые передаются только внутрь функции и должны уничтожаться вызывающим кодом, маркируются как [in]; аргументы, передаваемые ByRef, значение которых изменяется внутри функции, помечаются как [in, out]; в редких случаях используется и тип [out], когда функция получает указатель на неинициализированную переменную. Еще стоит отметить тип [out, retval] — он используется для описания возвращаемого типа для функций, описанных в интерфейсе. Такой параметр должен быть последним в списке.

Более подробное описание синтаксиса idl-файла вы можете найти в справке утилиты midl.

Автор:
Master

Предыдущий раздел

© 2004. При цитировании, пожалуйста, не забудьте поставить ссылку на оригинальную страницу.