[Lazarus] WinINet STDCALL callback crash
matthew at accordancebible.com
matthew at accordancebible.com
Wed Mar 13 17:51:29 CET 2013
Sven,
Thank you very much for your threading example below. I have used the model several times to build threaded implementations. However, I still get frequent, random segfaults when calling Windows functions. My current attempt, as simple as I can make it, is below. About 50% of the time, the first command in the execute procedure works fine; the other times it causes a crash. Might you or any others have suggestions on why this is?
Thank you,
Matthew
<pre>
TYPE
DownloadThread = CLASS(TThread)
PROCEDURE EXECUTE; OVERRIDE;
PUBLIC
theURL, theDest: AnsiString;
PUBLIC
CONSTRUCTOR Create(URLString: Str; dest: Str);
END;
VAR //global
gTheURLString: Str;
dest: Str;
IMPLEMENTATION
CONSTRUCTOR DownloadThread.Create(URLString: Str; dest: Str);
BEGIN
theURL := URLString;
theDest := dest;
FreeOnTerminate := True;
inherited Create(False);
END;
PROCEDURE DownloadThread.execute;
{ OVERRIDE }
VAR
hInet: HINTERNET;
hURL: HINTERNET;
Buffer: array[0..1023] of Byte;
BufferLen, amt: cardinal;
f: file;
success: BOOLEAN;
appTitle: PChar;
BEGIN
appTitle := 'Lazarus App with Threading';
try
hInet := InternetOpen(appTitle, INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
hURL := InternetOpenUrl(hInet, PChar(theURL), nil, 0, INTERNET_FLAG_RELOAD, 0);
try
FileMode := fmOpenWrite;
AssignFile(f, theDest);
try
Rewrite(f, 1);
amt := SizeOf(Buffer);
repeat
success := InternetReadFile(hURL, @Buffer, SizeOf(Buffer), BufferLen);
BlockWrite(f, Buffer[0], BufferLen, amt);
if Terminated then
Exit;
until BufferLen = 0;
finally
CloseFile(f);
end;
finally
InternetCloseHandle(hURL);
end;
FINALLY
InternetCloseHandle(hInet);
END;
END;
....main program...
DownloadThread.Create(gTheURLString, dest);
</pre>
-----Original Message-----
From: "Sven Barth" <pascaldragon at googlemail.com>
Sent: Monday, February 25, 2013 11:51am
To: lazarus at lists.lazarus.freepascal.org
Subject: Re: [Lazarus] WinINet STDCALL callback crash
On 25.02.2013 17:42, matthew at accordancebible.com wrote:
> Ludo, Hans-Peter,
>
> Many thanks for your insights.
>
> Ludo, I am reviewing the msdn code example you posted; I have read quite a few but don't remember seeing that one.
>
> Hans-Peter, our project has so far been able to avoid the additional complexity posed by threads. It would be with reluctance that we would turn to threading; however, if experimenting with Ludo's post content (see below) does not work, then would will use threads. Might you know of an example implementation or code for asynchronous HTTP and/or FTP downloads?
In principle you could do it as follows:
=== example begin ===
type
TDownloader = class(TThread)
public type
TCallback = procedure(aSender: TDownloader; aData: TStream) of object;
private
fCallback: TCallback;
fUrl: String;
protected
procedure Execute; override;
public
constructor Create(const aUrl: String; aCallback: TCallback);
end;
constructor TDownloader.Create(const aUrl: String; aCallback: TCallback);
begin
// check that aCallback and aUrl are given and set up local variables
// ...
FreeOnTerminate := True;
inherited Create(False);
end;
procedure TDownloader.Execute;
var
ms: TMemoryStream;
begin
ms := TMemoryStream.Create;
try
// here you use what ever synchronous API you want and store it's
result in ms
// when all data is received
fCallback(Self, ms);
finally
ms.Free;
end;
end;
// somewhere else
TDownloader.Create('http://example.org/whatever', @MyCallback);
// fire and forget
=== example end ===
Note: if you want to be able to cancel the download (which could be done
by calling the thread's "Terminate" method which sets "Terminated" to
"True") you should not set "FreeOnTerminate" to "True", check for
"Terminated" in the thread's "Execute" method and capture the instance
returned by "TDownloader.Create".
Regards,
Sven
--
_______________________________________________
Lazarus mailing list
Lazarus at lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
More information about the Lazarus
mailing list