2009年8月29日土曜日

Rttiを試してみるその4

以前のポストで、可視性がPrivateのメソッドは、読めないということを
記述しましたが、実際には、

自分で定義したメソッドであれば

コンパイラ指定{$RTTI EXPLICIT METHODS}で
TRttiContextのGetMehtodで列挙する可視性を制御することが可能のようです。

{$RTTI EXPLICIT METHODS([vcPublished,vcPublic,vcProtected,vcPrivate])}

とすれば、すべての可視性の列挙が可能です。(正し、継承元のメソッドには
可視性の制御は及ばない見たいです。)

また、

{$RTTI EXPLICIT METHODS([vcPrivate])}

とすれば、Private可視性のメソッドの列挙が可能です。

以下、検証ように使ったソースです。


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, CheckLst;

type
TForm1 = class(TForm)
Button1: TButton;
CheckListBox1: TCheckListBox;
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;

var
Form1: TForm1;

implementation

uses Rtti,Typinfo,Unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
ctx : TRttiContext;
rtmary : TArray;
rtm : TRttiMethod;
obj : TObject;
Args : Array of TValue;
rtp : TRttiType;
idx : Integer;
begin

ctx := TRttiContext.Create;

//自分で定義したメソッドのみを取得するには、
//GetDeclaredMethodsを使います。
rtmary := ctx.GetType(Unit2.TSakaTest).GetDeclaredMethods;
//rtmary := ctx.GetType(Unit2.TSakaTest).GetMethods();

CheckListBox1.Clear;

if rtmary <> nil then
begin
for rtm in rtmary do
begin
idx := CheckListBox1.Items.Add(rtm.Name);
if rtm.Visibility = TMemberVisibility.mvPrivate then
begin
CheckListBox1.Checked[idx] := true;
end;

end;

end;

end;

end.






unit Unit2;
interface

uses classes;

// {$RTTI EXPLICIT METHODS([vcPublished,vcPublic,vcPrivate])}
{$RTTI EXPLICIT METHODS([vcPrivate])}
Type TSakaTest = Class(TObject)
private
function SayPrivateMessage : String;
public
function SayPublicMessage : String;
End;

implementation

{ TSakaTest }

function TSakaTest.SayPrivateMessage: String;
begin
Result := 'This is a Private Method';
end;

function TSakaTest.SayPublicMessage: String;
begin
Result := 'This is a Public Method';
end;

end.

Rttiを試してみるその3

文字列で指定したクラスのインスタンスを作成する例を作ってみました。
(Button3Click)
試行錯誤のうえで作成したソースなので、とりあえず動きましたが
正しいソースかどうかは、分かりません。もっと良い方法が
あれば教えて下さい。

この手の処理はActivatorクラスのある.Netのほうが簡単だと
思います。


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls,Unit2;

type
TForm2 = class(TForm)
Button3: TButton;
LabeledEdit1: TLabeledEdit;
ListBox1: TListBox;
Button1: TButton;
Label1: TLabel;
procedure Button3Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
protected
public
{ Public 宣言 }

end;

var
Form1: TForm2;
implementation
uses
Rtti,TypInfo;

{$R *.dfm}


procedure TForm2.Button1Click(Sender: TObject);
var
LContext: TRttiContext;
LType: TRttiType;
LTypes:TArray;

begin

LoadPackage('SakaPack.bpl');

{ Obtain the RTTI context }
LContext := TRttiContext.Create;

{ Obtain the second package (rtl140) }
LTypes := LContext.GetTypes();

{ Enumerate all types in the rtl140 package }

//for LPackage in LPackages do
//begin
for LType in LTypes do
begin
ListBox1.Items.Add(LType.QualifiedName);
end;
//end;
ListBox1.Items.SaveToFile('P.Txt');

end;

procedure TForm2.Button3Click(Sender: TObject);
var
ctx : TRttiContext;
rtm : TRttiMethod;
rst : TValue;
SakaInf : ISakaTest;
rtt : TRttiType;
Args : Array of TValue;


begin

//とりあえず別パッケージで動的ロード化とする
LoadPackage('SakaPack.bpl');

ctx := TRttiContext.Create;

//文字列で型情報を探す場合は、FindTypeを使う
//完全一致なのでユニット名を含めて指定
rtt := ctx.FindType('Unit2.' + LabeledEdit1.Text);

//コンストラクタはとりあえずCreateであることが前提
rtm := rtt.GetMethod('Create');

if rtm <> nil then
begin
if rtm.IsConstructor then
begin
//1. クラスの場合は、TRttiInstanceTypeで戻ってくるのでキャスト
//2. MetaaclassTypeプロパティで実際のクラスがとれるみたい。
rst := rtm.Invoke(TRttiInstanceType(rtt).MetaclassType,Args);
if rst.IsObject Then
begin
SakaInf := TSakaTest(rst.AsObject) As ISakaTest;
Label1.Caption := SakaInf.SayMessage();
end;
//Label1.Caption := obj.ClassName;
end;
end;


end;

end.


でUnit2で使ったソースがこちら



unit Unit2;

interface
uses classes;

{$RTTI EXPLICIT METHODS([vcPublic])}
Type ISakaTest = interface(IInterface)
['{FAAA20A5-E078-4E22-96C2-139E7E57CBFB}']
function SayMessage : String;
end;

{$RTTI EXPLICIT METHODS([vcPublished,vcPublic])}
Type TSakaTest = Class(TInterfacedPersistent, ISakaTest)
function SayMessage : String; virtual;
End;

{$RTTI EXPLICIT METHODS([vcPublished,vcPublic])}
Type TSakaTest1 = Class(TSakaTest)
Public
function SayMessage : String; override;
End;

{$RTTI EXPLICIT METHODS([vcPublished,vcPublic])}
Type TSakaTest2 = Class(TSakaTest)
Public
function SayMessage : String; override;
End;

var
SakaTest : ISakaTest;

implementation

//uses
//Classes;



{ TSakaTest1 }

function TSakaTest1.SayMessage: String;
begin
Result := 'Hello Delphi First';
end;

{ TSakaTest2 }

function TSakaTest2.SayMessage: String;
begin
Result := 'Hello Delphi Second';
end;

{ TSakaTset }

function TSakaTest.SayMessage: String;
begin
Result := '';
end;

initialization
RegisterClass(TSakaTest);
RegisterClass(TSakaTest1);
RegisterClass(TSakaTest2);

end.

Jedi VCL Versionアップ

Delphi 2010の対応です。

ユニットを使うダイアログ


Unitの追加先を選択できるようになってたんだ。
気づかなかった。

Rttiを試して見るその2

前回のポストに引き続いて、メソッドの動的呼び出し。

整数の足し算を行う例です。以下ソース


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;

type
TForm1 = class(TForm)
Button3: TButton;
LabeledEdita: TLabeledEdit;
Label1: TLabel;
LabeledEditb: TLabeledEdit;
Label2: TLabel;
LabelResult: TLabel;
procedure Button3Click(Sender: TObject);
private
{ Private 宣言 }
protected
public
{ Public 宣言 }
function Sakasum(a,b : Integer) : Integer;

end;

var
Form1: TForm1;

implementation
uses
Rtti,TypInfo;

{$R *.dfm}


procedure TForm1.Button3Click(Sender: TObject);
var
ctx : TRttiContext;
rtm : TRttiMethod;
Args : Array of Rtti.TValue;
rst : TValue;
begin
//
ctx := TRttiContext.Create;
rtm := ctx.GetType(Self.ClassType).GetMethod('SakaSum');

if rtm <> nil then
begin
SetLength(Args,2);
//TValueは、演算子Implicitが定義されているので基本的な型は
//変換による代入が可能
Args[0] := StrToInt(LabeledEdita.Text);
Args[1] := StrToInt(LabeledEditb.Text);
rst := rtm.Invoke(Self,Args);
//結果はAsXXXXX関数を使って取り出せる。
Self.LabelResult.Caption := IntToStr(rst.AsInteger);
end;
end;


function TForm1.Sakasum(a, b: Integer): Integer;
begin
Result := a + b;
end;

end.


TValueの使い方が分からなくて結構悩みました。

で、ソースをみたら基本的な型については、
Implicit演算子のオーバーロードが
定義されているのね。

このへんはHelpに書いといて欲しかったです。
(C++ のHELPには書いてあります。)

(英語版のDoc Wikiがメンテナンス中だったので
日本語版でのみ書いていないのかはちょっと不明です。)

また、こちらにDelphi Prismで上記と同様な処理を
記述しました

2009年8月28日金曜日

Rttiを試して見る

動的にメソッドを読み出す簡単なプログラムを作ってみました。
プログラムそのものには意味はありません。

プレビュー会に説明があったようにprivateなメソッドは読めませんでした。
メソッドの可視属性を示す型があったので読めてもよいと思ったのですが・・・

また、GetDeclaredMethodsをつかうと自分が宣言したメソッドのみ
リストできます。

以下ソースです。


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
LabeledEdit1: TLabeledEdit;
Button2: TButton;
ListBox1: TListBox;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private 宣言 }
//procedure SakaTest2;
protected
//procedure SakaTest1;
procedure SakaTest2;
public
{ Public 宣言 }
procedure SakaTest2;
procedure SakaTest1;
end;

var
Form1: TForm1;

implementation
uses
Rtti,TypInfo;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
ctx : TRttiContext;
rtm : Rtti.TRttiMethod;
obj : TObject;
Args : Array of TValue;
begin
//
ctx := TRttiContext.Create;


//rtm := ctx.GetType(obj).GetMethod(LabeledEdit1.Text);

rtm := ctx.GetType(Self.ClassType).GetMethod(LabeledEdit1.Text);

if rtm <> nil then
begin
//obj := Self;
rtm.Invoke(Self,Args);
end;

end;

procedure TForm1.Button2Click(Sender: TObject);
var
ctx : TRttiContext;
rtmary : TArray;
rtm : TRttiMethod;
obj : TObject;
Args : Array of TValue;
rtp : TRttiType;
begin

ctx := TRttiContext.Create;

//rtm := ctx.GetType(obj).GetMethod(LabeledEdit1.Text);
//ctx.FindType()
//rtp := ctx.GetType(Self.ClassType);
//rtp.IsPublicType := false;

rtmary := ctx.GetType(Self.ClassType).GetDeclaredMethods;

ListBox1.Clear;

if rtmary <> nil then
begin
for rtm in rtmary do
begin
ListBox1.Items.Add(rtm.Name);
if rtm.Name = LabeledEdit1.Text then
begin
rtm.Invoke(Self,Args);
end;

end;

end;

end;

procedure TForm1.SakaTest1;
begin
Application.MessageBox('Hello Delphi','First Text');
end;

procedure TForm1.SakaTest2;
begin
Application.MessageBox('Hello Delphi','Second Text');
end;

end.


引数つきのメソッドコールはまた次回

2009年8月26日水曜日

サポートプログラムの配布方法

サポートプログラムの配布方法が
メールによるキー送付に変わった。

いち早く、使用できるのは良いが
やっぱりメディアもあったほうが
良いと思う。

2009年8月25日火曜日

プログラマがマニュアル読まなくどうするの

タイトルだけみて、気分を悪くされた方すみません。

これは、あくまでも自分への戒めのためのタイトルです。

DEKO様はじめ、先日、ご助言頂いた方々どうもありがとうございました。
なお、コメントは非公開と致しますのでご了承願います。

DelphiのHelpがWikiかされたので、ちょっとのぞいていたら
書いてあるんですわ。オブジェクトインスペクタの動作が・・・

ここに

大澤の親分の張本さんに大喝を食らったうえに
タイトルの台詞で叱咤されそうですわ。

しばらくは、懺悔と精進の日々です。

Rad Stduio 2010発売

正式発表があった見たいですね。

とりあえず、値段が据え置きでよかったです。
(スタンダードサポートの更新料も据え置きのようです。)

日本の公式サイトもエンバカデロドメインに移るようで
しばらくはばたばたしそうですね。

2009年8月23日日曜日

Delphiのウィルスについて思うこと

遅ればせながらひとこと。

エンバカデロさんからは、ウィルスに関する(対策)情報を
出す準備をしているとのこと
であり、コミュニティ方々も
いろいろな情報を出している。

しかし、現状、ウィルスに狙われているバージョンは4~7で、
エンバカデロさんのサポート情報によれば、すべて
サポート終了バージョンになっている。
(将来的には、新しいバージョンがターゲットになるかも
しれません。)

従って、Delphi4~7については、エンバカデロさんが
対策をしないと言ったとしても、僕らは、文句を言うことは
できないと思う。(言ってみるのは良いと思うが取り合って
くれない可能性のほうが高い。)

僕らにできることは、通常のウィルス対策と一緒のことですが
Delphiを最新の状態に保つこと。
すなわち、メーカのサポート中のバージョンの最新アップデートに
することだと思う。

ただ、開発言語(環境)で難しいのは、その環境の
過去バージョンで作ったアプリのサポートが必要だと
思う。

Versionを上げることは、Versionアップそのものの作業と
それに伴う動作検証に多大な労力がかかり、なおかつ
DelphiのVersionアップ料で多大な費用がかかることになる。

Delphiの開発元がBorland→Codegear->Embarcaderoと
変わる間にすくなくとも日本では、値段が高くなり
個人ユーザにはものすごい負担になると思う。

また、既にDelphiでの開発を止めている企業さんも多いと思う。
これらの企業さんは、メンテナンス用に古いバージョンを
保持しているとは思うが、いまさら新バージョン投資するかどうかは、
怪しいと思う。

ただし、個人的には、上記のような理由があっても、セキュアな
システムを提供するためにはVerupは提供する側の責任で
あると思う。

2009年8月18日火曜日

穴があったら入りたい。

コメント頂いた皆様ありがとうございました。

あまりのショボさに前のエントリーを非表示と致しました。

前のエントリーについては、期間をおいてなんらかの形で
復活させたいと思います。

しかし、10年以上使っててこんな初歩的なことを
しらなかったなんて・・・・

正に、穴があったら入りたい気分です。(穴はかなり深い穴が良いです。)

もう一回基本を固めて出直しです。

2009年8月14日金曜日

IDEの配置(その1)


上の図は、自分のIDEの配置です。
Visual Studioでオブジェクトインスペクタが右にあるのに
なれちゃったのでオブジェクトインスペクタは右側に
配置しています。

また、ツールパレットなど、構造ペインなども右側に
持っています。

これは、自分が右利きだからです。

意外に便利な配置なので、右利きの人は
良かったら試して下さい。

Rad Studio 2010の値段(米国)

Info Worldの記事によれば、エンプラ版のRad Studio 2010の米国での値段は
2799ドル(日本円で約26万7千円)だそうです。

さて、日本での値段はいくらになるのでしょうか?
ちょっと心配

2009年8月11日火曜日

思いつき

Delphi2010では、マウスジェスチャーがサポートされています。

これとWilリモコンを組み合わせたら、オモシロイことが出来そうですね。
(具体案は浮かばないので単なる思いつきですが・・・)

使い勝手にこだわれること

エンバカデロさんのサイト、フィールドテスターの皆様、ブロガーの皆様から
Delphi 2010に関する情報がいろいろ出てきてます。

これらを読むにつれて、地味だけど、かなり使い勝手を重視した機能を
盛り込んでいると思う。

これで、サクサク動けば、言うことなしなのですが、プレビュー会のビデオや
プレビュー動画を見る限りでは問題無さそうなのですが・・・

個人的には、使い勝手にこだわった開発が出来ているときは、
非常に良い状態で開発が出来ていると思います。

Delphi8から始まった製品の品質に関する混乱は完全に収束しつつある
といった状況と勝手に推測しています。

Delphi8の発売が2004年(本国は2003年11月)であることを考えると
会社自体の混乱もありましたが、品質を立て直すのに5年を要しています。

この間に失った信頼を取り戻すのは容易ではないかと思いますが、
現在の状態、(メーカさんとユーザさんとで適切にコミュニケーションが
とれている状態)であれば、なんとかなっていくのではないかと思います。

個人的には、発売前の情報で買いたいと思えるバージョンなのですが
問題は、価格ですね。(最近、Ver Upの度に価格があがっていますので・・・)

2009年8月6日木曜日

Delphi 2010 プレビュー会

仕事で参加できなかったかつ社内ネットワークから
中継が見れなかったので、とりあえずTwitterをROM

気になった点を以下列挙

1) RTTIの機能強化 Private メンバーは見れないみたいですね。
  Protectメンバーが見れれば良いのだけど、どうなんでしょう?

2) C++ 系で******_S系の関数が追加されたのはGoodです。

3) midasのソースコード有るんだ?ちょっとびっくりです。

参加者の皆さんお疲れ様でした。

今頃は、場所を変えて第2段かな?

Delphi 2010 の情報へのブックマーク

Nick Hodgesさんのブログポスト

Delphi2010の情報のブックマークになっています。

とりあえず、備忘録としてリンク

EmbarcderoのBlogでも、Radstudio 2010に関する記事が
ものすごい勢いで公開されています。

ついてくのがちょっと大変((^_^;))

2009年8月5日水曜日

Win32でリフレクション

日経ソフトウェアの記事によれば

Delphi2010では、.Netのリフレクション並にRTTIが強化される
見たいです。

これは楽しみ

DbExpress Firebird Driver

Delphi Feed経由の情報です。

次期Delphi2010でサポート予定のFirebirdですが、

Chee Yang ChauさんがDelphi2007, 2009対応の

FirebirdのDbExpressドライバを開発されました。

Firebird用のDbExpressドライバを探していたので
一度テストしてみる価値はありそうです。

開発者のChee Yang Chauさんに感謝です。

2009年8月4日火曜日

IDEインサイトは便利そう

次期Delphi(delphi2010)のPreview Videoが公開されたので
早速みてみた。

以下覚え書き(内容はVideoの要旨にも書かれてます。)

IDEインサートは、IDEの状況に応じて、専用のダイアログを使って
ショートカットを提供する機能で、Videoでは、IDEインサートから
Component名を入れてフォームに貼り付けるデモをしていた。

コンポーネント名さえ覚えていれば、コンポーネントパレットを
探さなくても(今までは、コンポーネントパレット内での検索可)
コンポーネントをフォームに貼れるので大変便利だ。

また、IDEでCode Formatterをサポートするようだ。
これは、DevCampでもリクエストがあった機能だ。

また、スレッドのデバッグ、TStringsのViewerなど
デバッグ時に便利な機能が追加されている。

細かいところでは、オブジェクトインスペクタの2値の設定が
チェックでできるようになっているみたいだ。

Videoの内容だけで判断すると2010はものすごく使い勝手に
こだわったVersionのような気がします。


でも、もっとも気になったなのはDavid Iの服の色目かな(冗談です。)

2009/08/05 追記

Nick Hodges氏もdelphi2010でIDEに新搭載の機能のブログを
POSTしています。