Форум: "Сети";
Текущий архив: 2005.10.23;
Скачать: [xml.tar.bz2];
ВнизЧто за проблемы с Indy в dll? Найти похожие ветки
← →
Aleksandr. (2005-07-01 13:32) [0]В динамической библиотеке работает класс на основе TidTCPClient (Indy 9). Если он хоть раз устанавливал соединение, при выгрузке библиотеки (FreeLibrary) проявляется неприятный эффект - программа зависает примерно на пару минут, и только после этого продолжает работу. Попытки трассировки уводят в дебри IdStackwindows:
finalization
if GStarted then begin
WSACleanup;
и далее, где-то в поисках адреса какой-то процедуры...
Никто не сталкивался с таким эффектом, как его залечить можно?
← →
Digitman © (2005-07-01 13:37) [1]покажи, где и как создаешь/уничтожаешь TidTCPClient, где и как обращаешься к нему
← →
Aleksandr. (2005-07-01 14:37) [2]Многовато будет...
в библиотеке:
const
FSession : TATISession=nil;
function InitSession(pParams : PChar) : longbool; stdcall;
begin
Result:=false;
try
FSession:=TATISession.Create(StrPas(pParams));
if FSession.Ready then begin
Result:=true;
FSession.Execute
end
except
end
end;
function DoneSession : longbool; stdcall;
begin
try
if FSession<>nil then begin
FSession.Free;
FSession:=nil
end;
Result:=true
except
Result:=false
end
end;
Сам объект, юзающий сессии:
type
TATISession = class
private
FClient : TIdTCPClient;
FSHandler : TIdIOHandlerSocket;
FSockInfo : TIdSocksInfo;
FSockType : TSocksVersion;
...
function OpenConnect : boolean;
procedure CloseHandlers;
procedure CloseConnect;
procedure EndSession;
public
procedure Execute;
destructor Destroy; override;
end;
constructor TATISession.Create(aParams : string);
var
L : TStrings;
begin
FEnded:=false;
FUseWinDial:=false;
FMainDir:=CheckDir(GetCurrentDir);
FClient:=TIdTCPClient.Create(nil);
L:=TStringList.Create;
try
L.Text:=aParams;
SetParams(L) // установка адреса, порта, тайм-аута
finally
L.Free
end
end;
procedure TATISession.Execute;
begin
if OpenConnect then try
...
finally
EndSession
end
end;
function TATISession.OpenConnect : boolean;
begin
Result:=false;
try
if NOT FClient.Connected then begin
if FIsProxy then begin
Status:=ccProxyConnect;
if NOT Assigned(FSHandler) then
FSHandler:=TIdIOHandlerSocket.Create(Self);
if NOT Assigned(FSockInfo) then
FSockInfo:=TIdSocksInfo.Create(Self);
FSHandler.SocksInfo:=FSockInfo;
if FProxyLogon then
FSockInfo.Authentication:=saUsernamePassword
else
FSockInfo.Authentication:=saNoAuthentication;
if FSockType IN [svNoSocks..svSocks5] then
FSockInfo.Version:=FSockType
else
FSockInfo.Version:=svNoSocks;
FSockInfo.Username:=FProxyLogin;
FSockInfo.Password:=FProxyPassword;
FSockInfo.Host:=FProxyHost;
FSockInfo.Port:=FProxyPort;
Self.IOHandler:=FSHandler
end
else
CloseHandlers;
Status:=ccConnect;
FClient.Connect;
FReceived:=0;
BytesReceived:=0;
FSended:=0;
BytesSended:=0;
FTotalSpeed:=0.0;
FTimeStart:=Now;
Status:=ccConnected;
FUserBreak:=false;
Result:=true
end
else
Result:=true
except
Status:=ccConnectError
end
end;
destructor TATISession.Destroy;
begin
Status:=ccDestroy;
try
if FClient.Connected then begin
Status:=ccDisconnect;
try
CloseConnect
except
on E:Exception do begin
Status:=ccExcept;
FClient.DisconnectSocket
end
end
end;
Status:=ccOK
finally
try
if Assigned(FSHandler) then
FreeAndNil(FSHandler);
if Assigned(FSockInfo) then
FreeAndNil(FSockInfo);
FreeAndNil(FParams);
FreeAndNil(FMoreParams);
FreeAndNil(FClient)
finally
inherited
end
end
end;
procedure TATISession.CloseHandlers;
begin
if Assigned(FSockInfo) then begin
// FSockInfo.Enabled:=false;
FreeAndNil(FSockInfo)
end;
if Assigned(FSHandler) then begin
FSHandler.Close;
FreeAndNil(FSHandler)
end
end;
procedure TATISession.CloseConnect;
begin
try
FClient.DisconnectSocket
except
end;
CloseHandlers;
Status:=ccDisconnected
end;
procedure TATISession.EndSession;
var
C : TRiTCPStatus;
begin
try
if FClient.Connected then try
Status:=ccDisconnect;
WriteStr(tcp_EndSession);
if StatusOk AND (ReadStr=tcp_OK) then
FClient.Disconnect;
CloseConnect;
Status:=ccDisconnected
except
try
DisConnectSocket;
Status:=ccDisconnected
except
Status:=ccExcept
end
end
finally
FTimeFinish:=Now;
Status:=ccOK
end
end;
Прокси не используются, поэтому создается один только TIdTCPClient. Ошибок не происходит, кстати, если не удалось установить соединение, то библиотека не провисает при выгрузке - только при удачной сессии.
← →
Digitman © (2005-07-01 15:14) [3]при иниц-ции / финализации библ-ки какие-то действия тобой производятся ?
покажи как ты грузишь / используешь эксп.вызовы / выгружаешь библ-ку, в каком кодовом потоке ...
← →
Aleksandr. (2005-07-01 18:30) [4]Initialization/finalization самой библиотеки пустой. Вызовы из программы:
var {глобальные}
vSesInitSession : function(pParams : PChar) : longbool; stdcall;
vSesDoneSession : function : longbool; stdcall;
procedure InitSessionProcs;
begin
hm_SesModule:=LoadLibrary(PChar(MainDir+SesModuleName));
@vSesInitSession :=GetProcAddress(hm_SesModule,"InitSession");
@vSesDoneSession :=GetProcAddress(hm_SesModule,"DoneSession")end;
procedure DoneSessionProcs;
begin
FreeLibrary(hm_SesModule)
end;
работа с сессией:
procedure TSessionThread.DoInitSession;
var
L, aParams : TStrings;
i : integer;
P : PChar;
begin
aParams:=TStringList.Create;
try
vInitSessionProcs(@usessionfrm.SesDllLog,@usessionfrm.TCPOnError,@usessionfrm.TCPOnStatus,
@usessionfrm.TCPFileInfo,@usessionfrm.TCPRasError,@usessionfrm.SessionFinish,
@usessionfrm.TCPOnMessage);
{$Region "обязательные параметры"}
aParams.Values[as_MainDir]:=MainDir;
aParams.Values[as_Host]:=ServerAddress;
aParams.Values[as_Port]:=IntToStr(ServerPort);
aParams.Values[as_InDir]:=InDir;
aParams.Values[as_OutDir]:=OutDir;
aParams.Values[as_TempDir]:=TempDir;
i:=as_Internal;
i:=i OR as_ReadWrite;
aParams.Values[as_TCPStatusFilter]:=IntToStr(i);
if FRegister then
aParams.Values[as_ConnectType]:=as_Registration
else
aParams.Values[as_ConnectType]:=as_UserQuery;
if IsCable then
aParams.Values[as_IsCable]:=as_Cable
else begin
aParams.Values[as_IsCable]:=as_DialUp;
if UseWinDialUp then
aParams.Values[as_UseWinDial]:=as_WinDial;
aParams.Values[as_DialName]:=DialUpName
end;
aParams.Values[as_UserID]:=IntToStr(UserCard.ID);
aParams.Values[as_Login]:=UserCard.Login;
aParams.Values[as_Password]:=UserCard.Password;
{$EndRegion}
aParams.Values[as_BlockSize]:=IntToStr(BlockSize);
if UseProxy then begin
aParams.Values[as_IsProxy]:=as_UseProxy;
aParams.Values[as_ProxyHost]:=ProxyHost;
aParams.Values[as_ProxyPort]:=IntToStr(ProxyPort);
if ProxyLogon then begin
aParams.Values[as_ProxyLogon]:=as_UseProxyLogon;
aParams.Values[as_ProxyLogin]:=ProxyLogin;
aParams.Values[as_ProxyPassword]:=ProxyPassword;
end;
aParams.Values[as_SockType]:=IntToStr(ProxyType)
end;
aParams.Values[as_MsgHandle]:=IntToStr(SessionForm.Handle);
aParams.Values[as_PatchVersion]:=IntToStr(PatchVersion);
P:=StrNew(PChar(aParams.Text));
try
vSesInitSession(P)
finally
StrDispose(P)
end
finally
aParams.Free
end
end;
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2005.10.23;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.038 c