BDEエリアスとTSession
BDEのエリアスからPATHを調べたい。
で、TSessionを使ってエリアスの一覧やエリアスの情報を得られますが、問題はこのTSessionの使い方です。
普通に TSession* session = new TSession (NULL); とかやって、セッション名を自動的につけるようにさせていました。
で、特定のエリアスのパスを返す関数を、実行時ライブラリにして、他のツールと共有しようと思った訳です。
まず、requiresに rtl.bpi, bdertl.bpi あたりが必要だったんですけど、これをコンパイルしたら普通にコンパイルが通って、パッケージライブラリと、インポートライブラリ、それから静的リンク用のライブラリとができあがったんですが、このパッケージライブラリを実行時ライブラリとして利用すると、bdertl.bplでメモリアクセス違反が出る。
で、どうやらTSessionList::AddSessionでTListにTThreadList.LockListを代入している所でエラーが起きてるようだ。
とりあえず、VCLはDelphiで、C++ではないが、こんな感じでbegin直後でエラーが起きるようだ。
DbTables.pas
で、調べてみたんですね。
そしたら、スレッドセーフにするため(?)に、Sessions変数のOpenSessionでオブジェクトを取得すればいいみたいですね。
この時、引数にセッション名を渡して、該当するセッションがあれば、そのセッションが返されて、該当セッションが見つからなければ、新しいセッションにその名前をつけて返してくれるらしい。
これが正しい使い方だったのか。
早速、パッケージを修正してから、サンプルプログラムを動かしたら、今度はエラーが出なくなった。
TSessionは基本的にはSessions変数からいただくものだったんですね。
ヤレヤレです。
ついでに見つけたんだが、borland\CBuilder6\source\vcl\Db.hppの1211行目あたりに、Currencyというプロパティがある。
TCurrencyFieldなんだが、TFloatFieldから派生している。
で、派生元クラスのTFloatFieldを見てみると、プロパティはcurrencyだ . . . 。
実際に、borland\cbuilder6\source\include\vcl\db.hppのTCurrencyField には小文字で書かれている。
C++では文字の大小を区別するので、これは別のプロパティとなる。
しかし、TCurrencyFieldでは、 __property Currency = {default=1}; と型もなく書かれていて、試しにちょっと工夫してこれをコンパイルしてみると、やはりここで、宣言エラーが不正だというエラーが出ますね。
で、先頭のCを小文字のcに変更してみました。
コンパイルも無事通りました。
うぅむ。
なんで、include\vcl\db.hppとsource\vcl\db.hppが違うのかは、勉強不足なのか全然わからん。
同じファイルのコピーじゃダメなんだろうか?
windowsなのでdiff見ないな物の手持ちもないので、比較はしていませんが実際どうなんでしょうね。
この頃はborlandだったもんな。
会社名がよく変わるツールだな。
インプライズになってボーランドに戻って、コードギアになってから、エンバカデロだもんな。
バージョンによってインストールされているディレクトリが全然違うから、戸惑うんだよな。
エンバカデロになってからバージョンアップしてないから、どんなもんだかわからないけど . . . 。
で、TSessionを使ってエリアスの一覧やエリアスの情報を得られますが、問題はこのTSessionの使い方です。
普通に TSession* session = new TSession (NULL); とかやって、セッション名を自動的につけるようにさせていました。
で、特定のエリアスのパスを返す関数を、実行時ライブラリにして、他のツールと共有しようと思った訳です。
まず、requiresに rtl.bpi, bdertl.bpi あたりが必要だったんですけど、これをコンパイルしたら普通にコンパイルが通って、パッケージライブラリと、インポートライブラリ、それから静的リンク用のライブラリとができあがったんですが、このパッケージライブラリを実行時ライブラリとして利用すると、bdertl.bplでメモリアクセス違反が出る。
で、どうやらTSessionList::AddSessionでTListにTThreadList.LockListを代入している所でエラーが起きてるようだ。
とりあえず、VCLはDelphiで、C++ではないが、こんな感じでbegin直後でエラーが起きるようだ。
DbTables.pas
procedure TSessionList.AddSession(ASession: TSession);
var
List: TList;
begin
List := FSessions.LockList; { ここでエラー発生!! }
try
if List.Count = 0 then ASession.FDefault := True;
List.Add(ASession);
finally
FSessions.UnlockList;
end;
end;
var
List: TList;
begin
List := FSessions.LockList; { ここでエラー発生!! }
try
if List.Count = 0 then ASession.FDefault := True;
List.Add(ASession);
finally
FSessions.UnlockList;
end;
end;
で、調べてみたんですね。
そしたら、スレッドセーフにするため(?)に、Sessions変数のOpenSessionでオブジェクトを取得すればいいみたいですね。
この時、引数にセッション名を渡して、該当するセッションがあれば、そのセッションが返されて、該当セッションが見つからなければ、新しいセッションにその名前をつけて返してくれるらしい。
これが正しい使い方だったのか。
早速、パッケージを修正してから、サンプルプログラムを動かしたら、今度はエラーが出なくなった。
TSessionは基本的にはSessions変数からいただくものだったんですね。
ヤレヤレです。
ついでに見つけたんだが、borland\CBuilder6\source\vcl\Db.hppの1211行目あたりに、Currencyというプロパティがある。
TCurrencyFieldなんだが、TFloatFieldから派生している。
で、派生元クラスのTFloatFieldを見てみると、プロパティはcurrencyだ . . . 。
実際に、borland\cbuilder6\source\include\vcl\db.hppのTCurrencyField には小文字で書かれている。
C++では文字の大小を区別するので、これは別のプロパティとなる。
しかし、TCurrencyFieldでは、 __property Currency = {default=1}; と型もなく書かれていて、試しにちょっと工夫してこれをコンパイルしてみると、やはりここで、宣言エラーが不正だというエラーが出ますね。
で、先頭のCを小文字のcに変更してみました。
コンパイルも無事通りました。
うぅむ。
なんで、include\vcl\db.hppとsource\vcl\db.hppが違うのかは、勉強不足なのか全然わからん。
同じファイルのコピーじゃダメなんだろうか?
windowsなのでdiff見ないな物の手持ちもないので、比較はしていませんが実際どうなんでしょうね。
この頃はborlandだったもんな。
会社名がよく変わるツールだな。
インプライズになってボーランドに戻って、コードギアになってから、エンバカデロだもんな。
バージョンによってインストールされているディレクトリが全然違うから、戸惑うんだよな。
エンバカデロになってからバージョンアップしてないから、どんなもんだかわからないけど . . . 。
| 固定リンク
| コメント (0)
| トラックバック (0)