C++Builder XEのIndy10のメール送信の動作がおかしい(Delphi XEのIndy10は問題ない)

最初に解決方法を書いておきます。

下記のコードを追加して、プロジェクトオプションの「実行時パッケージを使って構築」をチェックを外すと、問題が発生しなくなります。

#include <IdHeaderCoder2022JP.hpp>
#pragma link "IdHeaderCoder2022JP"

以下、本文です。

Dekoさんのところの記事「Indy 10 を使ってメール(ISO-2022-JP)を送受信するには? (Delphi 2009 以降)」を参考にしたメールを送信する次のコード。
(C++Builder XEでは、Delphi XEで作成したフォームをプロジェクトに追加して使用した。)

Delphi XEでは正しく動作したが、C++Builder XEではヘッダーの日本語が消えた。

procedure TForm1.IdMessage_InitializeISO(var VHeaderEncoding: Char; var VCharSet: string);
begin
  VHeaderEncoding := 'B';
  VCharSet := 'ISO-2022-JP';
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  SMTP: TIdSMTP;
  Msg : TIdMessage;
begin
  SMTP := TIdSMTP.Create(nil);
  try
    SMTP.Host     := 'localhost';
    SMTP.Port     := 25;
    SMTP.Connect;
    Msg := TIdMessage.Create(SMTP);
    try
      Msg.OnInitializeISO           := IdMessage_InitializeISO;
      Msg.ContentType               := 'text/plain';
      Msg.CharSet                   := 'ISO-2022-JP';
      Msg.ContentTransferEncoding   := 'BASE64';
      Msg.From.Name                 := '送信者123';
      Msg.From.Address              := 'from@localhost';
      Msg.Recipients.EMailAddresses := 'to@localhost';
      Msg.Subject                   := '件名123です';
      Msg.Body.Text                 := '本文123です';
      SMTP.Send(Msg);
    finally
      Msg.Free;
    end;
    SMTP.Disconnect;
  finally
    SMTP.Free;
  end;
end;

Delphi XEの送信結果は次のようなっている。これは正しい。

From: =?ISO-2022-JP?B?GyRCQXc/LjxUGyhCMTIz?= <from@localhost>
Subject: =?ISO-2022-JP?B?GyRCN29MPhsoQjEyMxskQiRHJDk=?=
To: to@localhost
Content-Type: text/plain; charset=ISO-2022-JP
Content-Transfer-Encoding: BASE64
Date: Sun, 16 Jan 2011 16:34:54 +0900

GyRCS1xKOBsoQjEyMxskQiRHJDkbKEINCg==

C++Builder XEの送信結果。差出人や件名の日本語の部分が消えている。

From: 23 <from@localhost>
Subject: 123
To: to@localhost
Content-Type: text/plain; charset=ISO-2022-JP
Content-Transfer-Encoding: BASE64
Date: Sun, 16 Jan 2011 16:35:19 +0900

GyRCS1xKOBsoQjEyMxskQiRHJDkbKEINCg==

C++で同じコードを書いてみる。

void __fastcall TForm2::IdMessage_InitializeISO(wchar_t &VHeaderEncoding, UnicodeString &VCharSet)
{
  VHeaderEncoding = L'B';
  VCharSet = "ISO-2022-JP";
}
void __fastcall TForm2::Button1Click(TObject *Sender)
{
  TIdSMTP* smtp = new TIdSMTP(NULL);
  smtp->Host = "localhost";
  smtp->Port = 25;
  smtp->Connect();

  TIdMessage* msg = new TIdMessage(NULL);
  msg->OnInitializeISO = IdMessage_InitializeISO;
  msg->ContentType = "text/plain";
  msg->CharSet = "ISO-2022-JP";
  msg->ContentTransferEncoding = "BASE64";
  msg->From->Name = "送信者123";
  msg->From->Address = "from@localhost";
  msg->Recipients->EMailAddresses = "to@localhost";
  msg->Subject = "件名123です";
  msg->Body->Text = "本文123です";
  smtp->Send(msg);

  smtp->Disconnect();
  delete msg;
  delete smtp;
}

実行結果は次の通り。変化なし。

From: 23 <from@localhost>
Subject: 123
To: to@localhost
Content-Type: text/plain; charset=ISO-2022-JP
Content-Transfer-Encoding: BASE64
Date: Sun, 16 Jan 2011 17:03:02 +0900

GyRCS1xKOBsoQjEyMxskQiRHJDkbKEINCg==

ということで、C++Builder XEのときだけ、動作がおかしいようだ。

追記

よくわからないまま、回避策が見つかった。

原因を調査していて、TIdHeaderCoder2022JP.Encodeの動作に疑問を持った。
IdHeaderCoder2022JP.pasを修正しようと思い、ファイルをコピーしてプロジェクトに追加した。
それから、メインフォームの先頭で”IdHeaderCoder2022JP.hpp”をincludeすると、問題が起こらなくなった。
なお、プロジェクトオプションの「実行時パッケージを使って構築」をチェックすると、問題は発生するようだ。

2011年3月10日 追記

IdHeaderCoder2022JP.pasのソースコードを読むと、次のコメントを見つけた。

// RLebeau 4/17/10: this forces C++Builder to link to this unit so
// RegisterHeaderCoder can be called correctly at program startup...
(*$HPPEMIT '#pragma link "IdHeaderCoder2022JP"'*)

そこで試しに次のコードを追加してみた。

#pragma link "IdHeaderCoder2022JP"

プロジェクトオプションの「実行時パッケージを使って構築」をチェックを外すと、問題が発生しなくなった。

コメント

  1. 私も最新のIndyのDevSnapshotとC++BuilderXEで試してみようと思います。

  2. 高橋智宏さま
    > 私も最新のIndyのDevSnapshotとC++BuilderXEで試してみようと思います。
    ありがとうございます。
    使用しているIndyはRadStudio XEに付属のものです。
    また回避策から考えると、私の環境だけの問題かもしれません。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください