Delphi2007で作成したプロジェクトをDelphi XE2に移植してみました。
通信量を減らす為にWebからのデータをgzip圧縮で受取っているのですが、XE2で実行すると「アドレスxxxxでアドレスxxxxxに対する読み取り違反が起きました。」というエラーが発生するようになってしまいました。
IdHTTP1.Compressorの行をコメントアウトすると、エラーが発生しなくなるので、TIdCompressorZLibでエラーが起きているようですが原因がわかりませんでした。
TIdZLibCompressorBase.DecompressGZipStreamにバグがあるみたいなことが書いてあった英文のサイトもありましたが、いつの記事なのかわかりませんでした。
サンプルプログラムを作ってみました。
procedure TForm1.Button1Click(Sender: TObject);
var
SL : TStringList;
MS : TMemoryStream;
ENC : TEncoding;
begin
IdHTTP1 := TIdHTTP.Create(Self);
IdHTTP1.Compressor := IdCompressorZLib1;
Memo1.Clear;
Memo1.Lines.Add('Indy10 Version:' + IdHTTP1.Version);
Memo1.Lines.Add('=======================');
IdHTTP1.ReadTimeout := 50000;
IdHTTP1.Request.Clear;
MS := TMemoryStream.Create;
SL := TStringList.Create;
ENC := TEncoding.GetEncoding(65001);
try
MS.Clear;
SL.Clear;
IdHTTP1.Get('http://www.google.co.jp/', MS);
finally
MS.Position := 0;
SL.LoadFromStream(MS, ENC);
Memo1.Lines.Add('Response-Text:' + IdHTTP1.ResponseText);
Memo1.Lines.Add('Content-Encoding:' + IdHTTP1.Response.ContentEncoding);
Memo1.Lines.Add('Content-Type:' + IdHTTP1.Response.ContentType);
Memo1.Lines.Add('Content-Length:' + IntToStr(IdHTTP1.Response.ContentLength));
Memo1.Lines.Add('=======================');
Memo1.Lines.Add(SL.Text);
MS.Free;
SL.Free;
end;
end;
Content-Encodingを見るとgzip圧縮で結果が返ってきているようですが、IdHTTP1.Getの所で例外が発生します。
使用しているOSはWindows XPです。
Indyのバージョンは10.5.8.0です。
プロジェクトにIndy10のソースを追加してデバッグを追跡していくと、IdZLib.pasのfunction LocalTryStreamType(AStreamType: TZStreamType): Boolean;のDCheck(inflateInitEx(strm, AStreamType));で例外が発生しているところまでわかりました。
inflateInitEx(strm, AStreamType)が存在しないアドレスを見にいっているようです。
zlibのdllかobjが存在していないか、パスが通っていないのでしょうか?
さらにソースを追跡して、IdZLibHeaders.pasで指定されている、zlib関連と思われる、objファイルが見つからないことが判りました。
Delphi XE2のバージョンがUpdate1のままで、なぜか自動更新も聞かなかったので、Delphi XE2を再インストールしてみましたが、現象は変わらなくて、objファイルも見つかりませんでした。
zlib homeのサイトからソースをダウンロードして自分でコンパイルしないといけないのでしょうか?
ツイート | ![]() |