наследование OVERLAPPED
От: Polevi  
Дата: 06.09.02 10:57
Оценка:
Люди помогите разобраться..
Работаю с портами завершения ввода-вывода.
Создаю свой класс-наследник структуры OVERLAPPED

class CDispatcher:public OVERLAPPED
{
public:
CDispatcher(SOCKET acceptSocket, SOCKET connectSocket)
{
Offset=0;
OffsetHigh=0;
Internal=0;
InternalHigh=0;
hEvent=0;
m_bufSize=8192;
m_buffer=VirtualAlloc(NULL,m_bufSize,MEM_COMMIT, PAGE_READWRITE);
m_status=FREE;
m_acceptSocket=acceptSocket;
m_connectSocket=connectSocket;
}

void Complete(DWORD dwNumBytes)
{
switch (m_status)
{
case READING: //завершилась операция чтения
ReadComplete(dwNumBytes);
break;
case WRITING: //завершилась операция записи
m_status=FREE; //готовы к чтению
case FREE:
ReadFile((HANDLE)m_acceptSocket,m_buffer,m_bufSize,NULL,this);
m_status=READING; //началась операция чтения
}
}

void ReadComplete(DWORD dwNumBytes)
{
WriteFile((HANDLE)m_connectSocket,m_buffer,dwNumBytes,NULL,this);
m_status=WRITING; //началась операция записи
}

private:
PVOID m_buffer;
DWORD m_bufSize;
int m_status;
SOCKET m_acceptSocket, m_connectSocket;
};


вот так выглядит поток, выбирающий сообщения из порта завершения

DWORD WINAPI WorkThreadProc(LPVOID lpParameter)
{
DWORD dwNumBytes, CompKey;
CDispatcher *disp;
for (;)
if (GetQueuedCompletionStatus(FCompPort->Handle,&dwNumBytes,
&CompKey, (OVERLAPPED **)&disp,INFINITE) && (dwNumBytes>0))
{
disp->Complete(dwNumBytes);
}
else
....
....
}

Все отлично работает, но !!!
При попытке сделать ф-ию ReadComplete виртуальной — объект портится — то есть когда в порту появляется сообщение о завершении асинхронной операции — управление передается в Complete но все поля объекта содержат мусор... (кроме OVERLAPPED !!!)
Давно не занимался C++ — может ошибка очевидна, но не для меня
Re: наследование OVERLAPPED
От: Alex Fedotov США  
Дата: 06.09.02 15:19
Оценка:
Здравствуйте Polevi, Вы писали:

P>Люди помогите разобраться..

P>Работаю с портами завершения ввода-вывода.
P>Создаю свой класс-наследник структуры OVERLAPPED

P>[...]


P>вот так выглядит поток, выбирающий сообщения из порта завершения


P>DWORD WINAPI WorkThreadProc(LPVOID lpParameter)

P>{
P>DWORD dwNumBytes, CompKey;
P>CDispatcher *disp;
P>for (;)
P>if (GetQueuedCompletionStatus(FCompPort->Handle,&dwNumBytes,
P>&CompKey, (OVERLAPPED **)&disp,INFINITE) && (dwNumBytes>0))
P>{
disp->>Complete(dwNumBytes);
P>}
P>else
P>....
P>....
P>}

P>Все отлично работает, но !!!

P>При попытке сделать ф-ию ReadComplete виртуальной — объект портится — то есть когда в порту появляется сообщение о завершении асинхронной операции — управление передается в Complete но все поля объекта содержат мусор... (кроме OVERLAPPED !!!)
P>Давно не занимался C++ — может ошибка очевидна, но не для меня :-)

Потому что запись (OVERLAPPED **)&disp в некотором смысле эквивалентна reinterpret_cast, а ты этого не хочешь. Надо переписать этот кусок примерно так:

OVERLAPPED * pOverlapped;
CDispatcher * pDisp;

if (GetQueuedCompletionStatus(..., &pOverlapped, ...))
{
    pDisp = static_cast<CDispatcher *>(pOverlapped);
    pDisp->Complete(dwNumBytes);
}
-- Alex Fedotov
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.