フォーム付DLLに別ユニット

解決


印刷屋  2007-11-23 18:13:04  No: 28638  IP: 192.*.*.*

プロジェクトが複雑化して、管理をしやすくするために初めてフォーム付DLLを作ってるんですが、いつもプロジェクト内でカテゴリー毎にユニット分けしていて、それをそのままDLLにするとポインタエラーとかが起きてしまいます。
DLL内で複数のユニットを結合管理するにはどうしたらいいんでしょうか?

DLL
∟Formユニット
∟DataModuleユニット(BDE管理)
∟関数専用ユニット(レジストリの読み書き)

FormユニットとDataModuleのCreateとFreeはしてます。

編集 削除
KHE00221  2007-11-24 00:34:42  No: 28639  IP: 192.*.*.*

何をどうしたらポインタエラーとかが起きますか?

とかということは他にも何かおきているのですか?

>それをそのままDLLにするとポインタエラーとかが起きてしまいます

そのままDLLにしてはいけないことをしてたりしてませんか?

String を使っていたり・・・stdcall 付け忘れとか?

あとDLLにフォームを使うとメモリーリークしますよ
(手動で修正すればしなくなりますが)

編集 削除
印刷屋  2007-11-24 01:07:33  No: 28640  IP: 192.*.*.*

デバッガ例外が発生…無効なポインタ操作、と出ます。

usesでお互いを見えるようにしておいて、Formの起動時・終了時にレジストリ用の関数でForm側の設定を読み書きをしたり、DataModuleに乗せたQueryから結果をForm側に送るようにしてるんですが、どうもそのユニット間の関数の行き来でエラーが起こることはわかりました。

もしかして、同DLL内でもユニット間のStringは問題あるんですか?

編集 削除
印刷屋  2007-11-24 01:23:24  No: 28641  IP: 192.*.*.*

あと、いいのか悪いのかわかりませんが、フォームの呼び出しは動的ロードで、
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を突っ込んで終わらせてます。

編集 削除
KHE00221  2007-11-24 08:56:05  No: 28642  IP: 192.*.*.*

DLL終了時に Application.Handle := nil をしてますか?

編集 削除
うんと  2007-11-24 11:45:34  No: 28643  IP: 192.*.*.*

>Application.Handle := nil 

Application.Handle := 0

かと

編集 削除
印刷屋  2007-11-26 02:43:55  No: 28644  IP: 192.*.*.*

フォームの起動・終了についてはなんとか解決しました。

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;
 
というコードの場合はどう書きなおせばいいんでしょうか?

編集 削除
KHE00221  2007-11-26 09:45:10  No: 28645  IP: 192.*.*.*

>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;

編集 削除
印刷屋  2007-11-26 11:16:38  No: 28646  IP: 192.*.*.*

複数の文字列を同時に入力したいので、手続きの方がいいんですよ。

で、Form側から呼んだ手続きで、
「モジュール'***.dll'のアドレス03C04611でアドレス00000058に対する読み込み違反が起きました。」
と出ます。

文頭のユニット名を省略してたので、付け足したんですが変わりません。

編集 削除
KHE00221  2007-11-26 11:26:42  No: 28647  IP: 192.*.*.*

DataModule を Unit1(FormCreate)で Create してますか?

編集 削除
印刷屋  2007-11-26 12:54:25  No: 28648  IP: 192.*.*.*

//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がきちんとできてないって事でしょうか。

編集 削除
印刷屋  2007-11-26 12:58:32  No: 28649  IP: 192.*.*.*

いろいろすいません。
これでいけました。

DMUnit.DataModule := TDataModule.Create(Application);

いろいろとお世話になりました。

編集 削除