プロジェクトが複雑化して、管理をしやすくするために初めてフォーム付DLLを作ってるんですが、いつもプロジェクト内でカテゴリー毎にユニット分けしていて、それをそのままDLLにするとポインタエラーとかが起きてしまいます。
DLL内で複数のユニットを結合管理するにはどうしたらいいんでしょうか?
DLL
∟Formユニット
∟DataModuleユニット(BDE管理)
∟関数専用ユニット(レジストリの読み書き)
FormユニットとDataModuleのCreateとFreeはしてます。
何をどうしたらポインタエラーとかが起きますか?
とかということは他にも何かおきているのですか?
>それをそのままDLLにするとポインタエラーとかが起きてしまいます
そのままDLLにしてはいけないことをしてたりしてませんか?
String を使っていたり・・・stdcall 付け忘れとか?
あとDLLにフォームを使うとメモリーリークしますよ
(手動で修正すればしなくなりますが)
デバッガ例外が発生…無効なポインタ操作、と出ます。
usesでお互いを見えるようにしておいて、Formの起動時・終了時にレジストリ用の関数でForm側の設定を読み書きをしたり、DataModuleに乗せたQueryから結果をForm側に送るようにしてるんですが、どうもそのユニット間の関数の行き来でエラーが起こることはわかりました。
もしかして、同DLL内でもユニット間のStringは問題あるんですか?
あと、いいのか悪いのかわかりませんが、フォームの呼び出しは動的ロードで、
var
ACreate:TCustomFormCreate;
GetModule:HMODULE;
begin
//DLL取得
GetModule := LoadLibrary('AAA.dll');
if GetModule <> 0 then
if GetProcAddress(GetModule,'FormCreateFunc') <> Nil then
begin
@ACreate := GetProcAddress(GetModule,'FormCreateFunc');
ACreate(Application.Handle);
end;
//DLL側
function FormCreate(hWnd: THandle):WordBool; stdcall;
begin
Application.Handle := hWnd;
Form1 := TForm1.Create(Application);
Form1.Show;
end;
閉じるときにOnCloseのActionにcaFreeを突っ込んで終わらせてます。
DLL終了時に Application.Handle := nil をしてますか?
>Application.Handle := nil
Application.Handle := 0
かと
フォームの起動・終了についてはなんとか解決しました。
with TForm1.Create(Application.Handle)do
begin
Top:= 0;
Left:=0;
Show;
end;
から
Form1 := TForm1.Create(Application.Handle);
Form1.Top := 0;
Form1.Left:= 0;
Form1.Show;
みたいにしたら直りました。
ただ、まだデータモジュールからフォーム書き出す方法について解決できてません。
uses Unit1;
Procedure TDataModule.BDE;
begin
Table.Open;
Unit1.Form1.Edit1.Text := Table.FieldByName('NAMAE').AsString;
Table.Close;
end;
というコードの場合はどう書きなおせばいいんでしょうか?
>with TForm1.Create(Application.Handle)do
>begin
> Top:= 0;
> Left:=0;
> Show;
>end;
これだと 変数Form1 に Form1 のポインタが代入されないので
with 〜 end の外で Form1 にアクセスできなくなります。(Form1 が nil のまま)
>Procedure TDataModule.BDE;
>begin
> Table.Open;
> Unit1.Form1.Edit1.Text := Table.FieldByName('NAMAE').AsString;
> Table.Close;
>end;
本来ならこんな形になると思うんですが(上記の書き方でも問題ないと思いますが)
何が解決してないんですか?(どんなエラー?)
fucntion TDataModule.BDE:String;
begin
Table.Open;
Result := Table.FieldByName('NAMAE').AsString;
Table.Close;
end;
複数の文字列を同時に入力したいので、手続きの方がいいんですよ。
で、Form側から呼んだ手続きで、
「モジュール'***.dll'のアドレス03C04611でアドレス00000058に対する読み込み違反が起きました。」
と出ます。
文頭のユニット名を省略してたので、付け足したんですが変わりません。
DataModule を Unit1(FormCreate)で Create してますか?
//DLL呼び出し
function CreateForm(hWnd: THandle):WordBool; stdcall;
begin
Result := False;
Application.Handle := hWnd;
DataModule.TDataModule.Create(Application);
Form1 := TForm1.Create(Application);
Form1.Show;
end;
Exports CreateForm;
こんな感じです。
やっぱCreateがきちんとできてないって事でしょうか。
いろいろすいません。
これでいけました。
DMUnit.DataModule := TDataModule.Create(Application);
いろいろとお世話になりました。
ツイート | ![]() |