初めまして、お世話になります。
下記のHPからダウンロードした実行ファイルは正常に動作するのですが、ソースをコンパイルするとエラーが出ます。
https://codezine.jp/article/detail/197
私の開発環境は、windows10 pro 64bitです。
Delphi 10.2を使っていますので、IndyはIndy10だと思います。
エラーはソース中の「←」で示す箇所で下記のエラーが出ます。
[dcc32 エラー] Unit1.pas(36): E2010 'TIdUDPListenerThread' と 'TObject' には互換性がありません
これを解決する方法を教えていただけないでしょうか。
UDPの利用例
procedure TForm1.FormCreate(Sender: TObject);
begin
// コンポーネントの設定
Memo1.Text := '';
IdUDPServer1.DefaultPort := 12345; // 適当なポートを使用
IdUDPServer1.OnUDPRead := IdUDPServer1UDPRead; // 受信時のイベント ←ここでエラーが発生
// UDPサーバーを起動する
IdUDPServer1.Active := True;
end;
// ボタンを押したら自分に対し'test'を送信する
procedure TForm1.Button1Click(Sender: TObject);
begin
IdUDPServer1.Send('127.0.0.1', 12345, 'test'); // 自分自身に送信
end;
// データを受信した時
procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
var
s: string;
begin
// TStreamを文字列に変換する
SetLength(s, AData.Size);
AData.Read(s[1], AData.Size);
// メモの先頭に受信した文字列を挿入
Memo1.Lines.Insert(0, s);
end;
Indyは、ほとんど使ったことがないので、詳しくないのですが、
Delphi10.2のTIdUDPServerのOnUDPReadイベントは、
procedure TForm1.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
const AData: TIdBytes; ABinding: TIdSocketHandle);
begin
end;
みたいなので、
> // データを受信した時
> procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
> ABinding: TIdSocketHandle);
の引数を、同じように合わせるのがよさそうですね。
>Delphi 7に付属しているIndy 9のコンポーネントを利用して、手軽に作ってみます。
Indy9 用だよねソース
ソース会員じゃないとダウンロードできないし
[dcc32 エラー] Unit1.pas(36): E2010 'TIdUDPListenerThread' と 'TObject' には互換性がありません
の原因は
Indy9 と Indy10 の IdUPDServer の OnUPDRead のイベントの型が違うから
//Indy9
procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
//Indy10
procedure TForm1.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
const AData: TIdBytes; ABinding: TIdSocketHandle);
1個目のパラメータが Sender: TObject; と AThread: TIdUDPListenerThread;
と型に互換性がないと
イベントを付けなおせばいけるけど今度は
AData の型が違うからそこ直さないと駄目
AData: TStream; //Indy9
AData: TIdBytes; //Indy10
早速のご返答ありがとうございます。
教えていただいたように書き直してみたのですが、TIdBytesが未定義の識別子になってしまいます。
> procedure TForm1.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
> const AData: TIdBytes; ABinding: TIdSocketHandle);
^^^^^^^^
これを解決するにはどうすれば良いのでしょうか
因みに、元のソースファイルは下記のとおりです。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdUDPBase, IdUDPServer,
IdSocketHandle;
type
TForm1 = class(TForm)
IdUDPServer1: TIdUDPServer;
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
procedure FormCreate(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
// コンポーネントの設定
procedure TForm1.FormCreate(Sender: TObject);
begin
IdUDPServer1.DefaultPort := 12345;
IdUDPServer1.OnUDPRead := IdUDPServer1UDPRead;
IdUDPServer1.Active := True;
Memo1.Text := '';
end;
// ボタンを押したら全員に対し'test'を送信する
procedure TForm1.Button1Click(Sender: TObject);
begin
IdUDPServer1.Broadcast('test',12345);
end;
// データを受信した時
procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
var
s: string;
begin
SetLength(s, AData.Size);
AData.Read(s[1], AData.Size);
Memo1.Lines.Insert(0, s);
end;
end.
uses に、IdGlobal を追加してみるのは、いかがですか?
おかげさまで、TIdBytesのエラーは直りましたが
AData.SizeとAData.Readが「TIdBytesはSizeとReadという名前のメンバを含んでいません」となります。
これはどうしたらよろしいのでしょうか。
// データを受信した時
procedure TForm1.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
const AData: TIdBytes; ABinding: TIdSocketHandle);
var
s: string;
begin
SetLength(s, AData.Size);
AData.Read(s[1], AData.Size);
Memo1.Lines.Insert(0, s);
end;
ソースコードみたら、
TIdBytes = array of Byte;
みたいです。
私はランクを中級者としましたが、s23年生まれで、昔はTurboPascalをかなり使っていましたが、Delphiになってからは基本が理解出来ていないため、いまいち分からないことが多すぎて困っております。
特に、ソケット通信は初めてのチャレンジです。
できましたら、具体的にどこをどう直せば良いのか、ご教授いただけないでしょうか。
申し訳ありませんが、よろしくお願いいたします。
>具体的にどこをどう直せば良いのか、ご教授いただけないでしょうか。
ご教授などとたいそうなことはできません.
TIdBytes = array of Byte;
というのはバイト配列のことです.
ですので,バイト配列を文字列にします.
Broadcast では ASCII 文字しか送信できないようなので string 型ではなく AnsiString 型を使用します.
AnsiString の ASCII 文字は 1 バイトが 1 文字です.
procedure TForm1.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
const AData: TIdBytes; ABinding: TIdSocketHandle);
var
s: AnsiString;
begin
SetLength(s, Length(AData));
Move(AData[0], s[1], Length(AData));
Memo1.Lines.Insert(0, string(s));
end;
>申し訳ありませんが、よろしくお願いいたします。
提示されたキーワードを頼りに Google 等で検索するとよろしいかと.
それと,ネット上のこういう掲示板では,年齢,男女,経歴,地位はあまり関係ないと思います.
年をとっていることは免罪符にはなりません.多分
Move 関数を使用するというは思いつかないことがあります.
そんな時は以下のように 1 バイトづつ処理することも可能です.
AnsiString, AnsiChar を使用するのがミソというかポイントですね.
procedure TForm1.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
const AData: TIdBytes; ABinding: TIdSocketHandle);
var
LIndex : Integer;
LText : AnsiString;
begin
LText := '';
for LIndex := 0 to Length(AData) - 1 do begin
LText := LText + AnsiChar(AData[LIndex]);
end;
Memo1.Lines.Insert(0, string(LText));
end;
ゴメンなさい.TEncoding を使えば簡単でした.
procedure TForm1.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
const AData: TIdBytes; ABinding: TIdSocketHandle);
var
LString : string;
begin
LString := TEncoding.ASCII.GetString(AData);
Memo1.Lines.Insert(0, LString);
end;
igyさん、AAAさん、Mr.XRAYさん、ご回答ありがとうございました。
おかげさまで、解決することができました。
これからも新しいことにチャレンジして行けそうです。
> 年をとっていることは免罪符にはなりません.多分
つい甘えてしまい、申し訳ありませんでした。
これからも、生涯現役のつもりで頑張ります。
ものはついでと言います
このスレッドを読んでいて,実際にサンプルょをやってみて,日本語は ?
と思った方,以下にサンプルがあります.
( 検索すれば見つかるわけですが...)
[ TIdUDPServerで日本語文字列を送受信するには ? 山本隆の開発日誌 ]
https://www.gesource.jp/weblog/?p=6036
Delphi のコードにすると,例えば以下のようになると思います.
procedure TForm1.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
const AData: TIdBytes; ABinding: TIdSocketHandle);
var
LString : string;
begin
LString := TEncoding.Unicode.GetString(AData);
Memo1.Lines.Insert(0, LString);
end;
// ボタンを押したら文字列を送信する
procedure TForm1.Button1Click(Sender: TObject);
begin
//文字列をUTF16LEで送信する
//自分自身に送信
IdUDPServer1.Send('127.0.0.1', 12345, '日本語 ABC 文字列', IndyTextEncoding_UTF16LE);
end;
実行時に現れるダイアログについては以下を参考にしてください.
例によって「難解」な記事ですのであしからず.
[ Windows セキュリティの重要な警告 ] ダイアログ ]
http://mrxray.on.coocan.jp/Delphi/Others/MicrosoftSecurity.htm
ツイート | ![]() |