Форум: "Потрепаться";
Текущий архив: 2003.01.06;
Скачать: [xml.tar.bz2];
ВнизВопрос не понятно какой темы, в общем наверное потоки виноваты Найти похожие ветки
← →
cyborg (2002-12-16 23:39) [0]Вопрос относится к многим темам и не знаю куда больше.
Проблема вот в чём, как до меня дошло, интерфейсы DirectPlay относятся к ActiveX, работают в многопотоковом режиме, ну кто знает, тот поймёт :). Проблема вот в чём, когда пытаюсь прочитать или записать пришедшие данные, в частности ошибка появляется при приходе сообщения о подключившимся игроке, конкретно когда по указателю пытаюсь присвоить своим данным ID игрока из указанных данных события подлключения игрока и часто появляется ошибка Access violation адреса такого-то в модуле "dpnet.dll" Read of adress такой-то, иногда не появляется.
В примерах на С++ имеются такие функции:
InitializeCriticalSection( &g_csPlayerContext );
EnterCriticalSection( &g_csPlayerContext )
LeaveCriticalSection( &g_csPlayerContext )
DeleteCriticalSection( &g_csPlayerContext );
Видимо они избавляют от даной проблемы, но так как я, мягко говоря, с С++ не дружу, то так и не понял как их использовать, откуда берётся этот &g_csPlayerContext, и что это такое, вообще не пойму этой переменной, как она связана с данными в том примере?
Пимер этого кода на С++ можно посмотреть здесь:
http://csislabs.palomar.edu/Student/dx81/DXSDK/samples/Multimedia/DirectPlay/ChatPeer/
Подскажите пожалуйста откуда берётся этот &g_csPlayerContext, и как вообще избавиться от таких ошибок, может пример их написания на Паскале покажите?
← →
cyborg (2002-12-17 11:37) [1]UP
← →
Ketmar (2002-12-17 11:59) [2]RTFM Critical Sections.
Satanas Nobiscum! 17-Dec-XXXVII A.S.
← →
han_malign (2002-12-17 12:02) [3]Во первых - это не ActiveX и даже не OLE - а DirectX - чисто COM(нафиг ему, спрашивается, Dispatch и контейнеризация если это чисто API прослойка над железом, с фиксированным интерфейсом).
Во втрых - uses Windows - TRtlCriticalSection и те-же самые процедуры, а "этот &g_csPlayerContext" это поле объекта(если делаешь объектную обвязку) или глобальная переменная(в данном случае учитывая преффикс g_ , согласно венгерской нотации, это как раз глобальная переменная), типа TRtlCriticalSection.
В третьих - объекты синхронизации(к коим и относится критическая секция), нужны при совместном использовании несколькими потоками одного ресурса. Объяснять принципы построения многопоточных приложений - это семинар на несколько месяцев, к тому-же, умом понимаю, а объяснить не смогу, из институтского курса понял только терминологию, а вот как все это работает, и откуда в NT 3.5(в остальных не знаю - может исправили), на самом безобидном мутанте, при определенной последовательности запросов разного приоритета - может deadlock появиться - это понял только пройдя через огонь, воду и медные трубы.
З.Ы. Короче дерзайте, ибо дорога сия терниста и полна неожиданностей.
← →
cyborg (2002-12-17 12:54) [4]чисто COM(нафиг ему, спрашивается,
CoInitializeEx( Nil, COINIT_MULTITHREADED);
hr := CoCreateInstance( CLSID_DirectPlay8Peer, nil, CLSCTX_INPROC_SERVER, IID_IDirectPlay8Peer, iDP8Peer );
Вот так там используется ActiveX, я никогда с ActiveX до этого дела не имел, мне не нужно расписывать как работает мультипоточность, я никак не пойму в том исходнике откуда взялось это &g_csPlayerContext, на что оно указывает там, чтобы мне сделать тоже самое на Паскале, ну не вижу я там что такое это &g_csPlayerContext, покажите пожалуйста?
← →
Ketmar (2002-12-17 13:24) [5]билат. ну сказали же. кто по-аглицки, кто по-русски. это простая переменная типа TRTLCriticalSection. как с ней работать (и вообще про critical sections) написано в Win32 SDK Help или у того же Рихтера. "шо неясно?" (ц)
Satanas Nobiscum! 17-Dec-XXXVII A.S.
← →
cyborg (2002-12-17 14:01) [6]Ketmar © не дёргайся, я знаю что тs вумный, с этим никто не спорит, ты бы лучше сказал как связана эта &g_csPlayerContext с данными от DirectPlay.
билат.
← →
cyborg (2002-12-17 14:11) [7]Вот вставил я эти
EnterCriticalSection( csPlayerContext );
TDPNMsg_Create_Player(pMessage^).pvPlayerContext := @Players[0];
LeaveCriticalSection( csPlayerContext );
Вообще труба стала, теперь при каждом приходе любого сообщения после прихода подключения игрока вылезают ошибки
← →
Ketmar (2002-12-17 14:18) [8]а остальной код? в частности, InitializeCriticalSection ты делаешь? или Папа Карло за тебя должен? почитай хэлп, а? сразу куча вопросов отвалится...
Satanas Nobiscum! 17-Dec-XXXVII A.S.
← →
cyborg (2002-12-17 14:20) [9]Всё, вопрос вроде пока снят, ошибка возникала при отправке, хотя всё равно не понятно.
← →
cyborg (2002-12-17 14:22) [10]InitializeCriticalSection ты делаешь?
Скажем так, не стоит меня не дооценивать.
← →
cyborg (2002-12-17 14:27) [11]Кстати, Папа Карло тоже иногда не плохо делает. :)
← →
Ketmar (2002-12-17 14:40) [12]>cyborg © (17.12.02 14:22)
ну мало ли... я ж сказал: код в студию. а остальное так - прикладная телепатия %-))
Satanas Nobiscum! 17-Dec-XXXVII A.S.
← →
cyborg (2002-12-17 15:39) [13]:) Ketmar © хитрый, это секрет фирмы, просто никто мне не мог объяснить как работает DirectPlay поэтому я решил, что тут никто не знает этого дела, если приведу часть кода никто не поймёт что там куда делается, тем более комментраиев я там не писал :(, а приводить весь код чтобы было понятно, там много понаписано, сюда же не писать весь модуль!? Согласен, что без кода трудно отвечать, но вопрос стоял в том, чтобы мне объяснили как переделать сишный код относящийся к ..., который в ссылке в первой мессаге.
← →
cyborg (2002-12-17 15:50) [14]В общем вот код:
function SendMsg( ToID: Cardinal; Data: Pointer; Size: Cardinal; Flags: DWord; TimeOut: Integer = 0 ): HResult;
var
AsyncHandle : TDPNHandle;
BufferDesc : TDPN_Buffer_Desc;
hr : HResult;
begin
BufferDesc.pBufferData := Data;
BufferDesc.dwBufferSize := Size;
hr := IDP8Peer.SendTo( ToID, BufferDesc, 1, TimeOut, nil, @AsyncHandle, Flags );
Result := hr;
end;
function HandleMessage(pvUserContext: Pointer; dwMessageType: LongWORD; pMessage: Pointer): HResult; stdcall;
var
DPNMsg_Receive : TDPNMsg_Receive;
Msg_PlayerID : TMsg_PlayerID;
Msg_Request : TMsg_Generic;
begin
MsgEvent := [];
case dwMessageType of
DPN_MSGID_CREATE_PLAYER:
begin
if Players[0].DPID = 0 then
begin
TDPNMsg_Create_Player(pMessage^).pvPlayerContext := @Players[0];
PPlayer(PDPNMsg_Create_Player(pMessage)^.pvPlayerContext).DPID := TDPNMsg_Create_Player(pMessage^).dpnidPlayer;
end else
if Players[1].DPID = 0 then
begin
Players[1].DPID := TDPNMsg_Create_Player(pMessage^).dpnidPlayer;
TDPNMsg_Create_Player(pMessage^).pvPlayerContext := @Players[1];
end;
Msg_Request.dwType := MsgID_PlayerInfo_Request;
ошибка тут возникает иногда при отсылке:
SendMsg( TDPNMsg_Create_Player(pMessage^).dpnidPlayer, @Msg_Request, SizeOf(TMsg_Generic), DPNSEND_GUARANTEED );
MsgEvent := MsgEvent + [evPlayerlistChanged];
Form1.Memo1.Lines.Add("??????????? ?????, ID:"+IntToStr(TDPNMsg_Create_Player(pMessage^).dpnidPlayer));
end;
DPN_MSGID_DESTROY_PLAYER:
begin
PPlayer(PDPNMsg_Destroy_Player(pMessage)^.pvPlayerContext)^.DPID:=0;
// broadcast a message to inform all other players that someone has quit
Msg_PlayerID.dwType := MsgID_RemovePlayer;
Msg_PlayerID.PlayerID := PDPNMsg_Destroy_Player(pMessage)^.dpnidPlayer;
BroadcastMsg( @Msg_PlayerID, SizeOf(TMsg_PlayerID), DPNSEND_GUARANTEED );
MsgEvent := MsgEvent + [evPlayerlistChanged];
Form1.Memo1.Lines.Add("?????????? ?????, ID:"+IntToStr(TDPNMsg_Create_Player(pMessage^).dpnidPlayer));
end;
...
end;
...
Result := S_OK;
end;
← →
Ketmar (2002-12-17 16:21) [15]так вопрос снят, или где??
Satanas Nobiscum! 17-Dec-XXXVII A.S.
← →
cyborg (2002-12-17 16:56) [16]Снят, насчёт проблемы отправки это уже другой вопрос, буду ковырять дальше.
Страницы: 1 вся ветка
Форум: "Потрепаться";
Текущий архив: 2003.01.06;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.008 c