Страница 1 из 1

Гад делегат (c#)

Добавлено: 24 дек 2005, 19:33
vg
Шутка, конечно, но не знаю, как лучше сделать. Подскажите, пожалуйста.

Положим, callback-функция имеет прототип:

Код: Выделить всё

void CALLBACK InternetStatusCallback(
  HINTERNET hInternet,
  DWORD_PTR dwContext,
  DWORD dwInternetStatus,
  LPVOID lpvStatusInformation,
  DWORD dwStatusInformationLength
);
Здесь интересует определение LPVOID lpvStatusInformation в делегате. Для различных DWORD dwInternetStatus этот указатель должен быть приведён к различному типу.
Например, если dwInternetStatus == INTERNET_STATUS_REQUEST_SENT, то lpvStatusInformation представляет адрес DWORD bytesOut.

Для этого частного случая не составит труда определить и имплементировать делегат:

Код: Выделить всё

	public delegate void InternetCallBack ( IntPtr hInternet,
								int context,
								int dwInternetStatus,
								ref int lpvStatusInformation,
								int dwStatusInformationLength );

Код: Выделить всё

		public static void m_iCallBack ( IntPtr hInternet,
			int context,
			int dwInternetStatus,
			ref int lpvStatusInformation,
			int dwStatusInformationLength )
		{

			if ( INTERNET_STATUS_REQUEST_SENT == dwInternetStatus )
			{
				
				m_BytesOut += lpvStatusInformation;

				<skip>
				bla-bla-bla
			}
		}
Для других значений dwInternetStatus - lpvStatusInformation должна быть интерпретироваться совершенно иначе, например, как указатель на некую структуру. Например, если dwInternetStatus == INTERNET_STATUS_HANDLE_CREATED, то lpvStatusInformation представлялет указатель на структуру:

Код: Выделить всё

typedef struct {
  DWORD dwResult;
  DWORD dwError;
} INTERNET_ASYNC_RESULT, 
* LPINTERNET_ASYNC_RESULT;
Это потребовало бы другого определения делегата. Как сделать, чтобы можно было использовать один делегат? Может определить в делегате LPVOID lpvStatusInformation как, например, int или char*, а затем выполнять приведение типов в unsafe секции С# кода?

Спасибо.

Добавлено: 25 дек 2005, 13:11
vg
Вопрос закрыт.
"Надо объявить lpvStatusInformation как IntPtr а потом, можно воспользоваться Marshal.PtrToStructure". Работает.