全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2249
推到 Plurk!
推到 Facebook!

釋放DLL時會報錯!

答題得分者是:jow
shine0989
一般會員


發表:9
回覆:31
積分:8
註冊:2008-06-21

發送簡訊給我
#1 引用回覆 回覆 發表時間:2010-05-10 18:01:02 IP:123.204.xxx.xxx 訂閱
小弟又來打擾了..><"

請問各位先進...

小弟目前碰到一個問題..
就是要釋放DLL時..會錯報!!!!

以下為呼叫DLL的程式碼↓


[code delphi]


//load dll
ADllHandle := SafeLoadLibrary(formName);
//try
if ADllHandle<>0 then
ProcAddr := GetProcAddress(ADllHandle, 'GetChildForm');
if ProcAddr<>nil then
begin
GetChildForm := TGetChildForm(ProcAddr);
GetChildForm(Self,ClassName,f);
end;
finally
FreeLibrary(ADllHandle); //這裡會報錯!!!!
end;


[/code]


先感謝各位先進喔..^^
syntax
尊榮會員


發表:26
回覆:1139
積分:1258
註冊:2002-04-23

發送簡訊給我
#2 引用回覆 回覆 發表時間:2010-05-11 08:46:11 IP:59.125.xxx.xxx 訂閱
Free the Form you make, First
===================引 用 shine0989 文 章===================
小弟又來打擾了..><"

請問各位先進...

小弟目前碰到一個問題..
就是要釋放DLL時..會錯報!!!!

以下為呼叫DLL的程式碼↓


[code delphi]


//load dll
ADllHandle := SafeLoadLibrary(formName);
//try
if ADllHandle<>0 then
ProcAddr := GetProcAddress(ADllHandle, 'GetChildForm');
if ProcAddr<>nil then
begin
GetChildForm := TGetChildForm(ProcAddr);
GetChildForm(Self,ClassName,f);
end;
finally
FreeLibrary(ADllHandle); //這裡會報錯!!!!
end;


[/code]


先感謝各位先進喔..^^
shine0989
一般會員


發表:9
回覆:31
積分:8
註冊:2008-06-21

發送簡訊給我
#3 引用回覆 回覆 發表時間:2010-05-11 09:25:01 IP:123.204.xxx.xxx 訂閱

感謝syntax大大的回覆..^^

請問大大~
是要先把FORM先FREE掉嗎??

===================引 用 syntax 文 章===================
Free the Form you make, First
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#4 引用回覆 回覆 發表時間:2010-05-11 12:30:58 IP:118.169.xxx.xxx 未訂閱
發生錯誤的訊息是啥?
是不是 Access Error read 0x... can not write 0x.....
多半是dll本身程式在結束時釋放了不恰當的物件或變數, 導致 freedll時找不到這些位址而引發錯誤,
所以你應該先就原有的dll檔去追查一下結束時的動作
shine0989
一般會員


發表:9
回覆:31
積分:8
註冊:2008-06-21

發送簡訊給我
#5 引用回覆 回覆 發表時間:2010-05-11 15:03:30 IP:123.204.xxx.xxx 訂閱
感謝P.D. 版主的回覆..

小弟的錯誤訊息是↓
Access violation at address 4003BA4F in module 'rtl70.bpl'. Read of address 0B128620'

小弟現在還在努力在找問題..><"
已從G大神那找過一遍了..都找不到結決的答案....!!

===================引 用 P.D. 文 章===================
發生錯誤的訊息是啥?
是不是 Access Error?read 0x... can not write 0x.....
多半是dll本身程式在結束時釋放了不恰當的物件或變數, 導致 freedll時找不到這些位址而引發錯誤,
所以你應該先就原有的dll檔去追查一下結束時的動作
syntax
尊榮會員


發表:26
回覆:1139
積分:1258
註冊:2002-04-23

發送簡訊給我
#6 引用回覆 回覆 發表時間:2010-05-12 08:47:51 IP:59.125.xxx.xxx 訂閱
只要是你自己宣告的,都必須在 FreeLibrary(ADllHandle); 前釋放

===================引 用 shine0989 文 章===================

感謝syntax大大的回覆..^^

請問大大~
是要先把FORM先FREE掉嗎??

===================引 用 syntax 文 章===================
Free the Form you make, First
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#7 引用回覆 回覆 發表時間:2010-05-12 09:44:02 IP:112.104.xxx.xxx 未訂閱
在每個ButtonClick動作中卸載DLL檔
可能會動到Child Form 的相關資源
即使用 {$R *.dfm} 連結的資源檔
Child Form 所佔記憶體結構將無法被描述
以上純屬推測, 請自行驗證...
所以你只能做到以下程度的動態載入
在FormCreate, FromClose載入及卸載DLL檔
以下程式碼供你參考
[code delphi]
unit fMain;

interface
uses
Windows, Classes,Forms, StdCtrls, Controls, ExtCtrls;

type
TGetChildForm = function(MDIMainForm: TForm; AClassName: string; var f: TForm): Boolean; safecall;

TfrmMain = class(TForm)
Panel1: TPanel;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
public
h: THandle;
x: TGetChildForm;
end;

var
frmMain: TfrmMain;

implementation

{$R *.dfm}

procedure TfrmMain.FormCreate(Sender: TObject);
begin
@x := nil;
h := LoadLibrary('TestDll009.dll');
if h > 0 then
begin
@x := GetProcAddress(h,'GetChildForm');
end;
end;

procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
@x := nil;
if h > 0 then
begin
FreeLibraryAndExitThread(h,0);
end;
end;

procedure TfrmMain.Button1Click(Sender: TObject);
var
f: TForm;
begin
if Assigned(x) and x(Self,'TfrmChild1',f) then
begin
f.WindowState := wsNormal;
f.BringToFront;
end;
end;

procedure TfrmMain.Button2Click(Sender: TObject);
var
f: TForm;
begin
if Assigned(x) and x(Self,'TfrmChild2',f) then
begin
f.WindowState := wsNormal;
f.BringToFront;
end;
end;

end.
[/code]
^_^


shine0989
一般會員


發表:9
回覆:31
積分:8
註冊:2008-06-21

發送簡訊給我
#8 引用回覆 回覆 發表時間:2010-05-12 11:34:24 IP:123.204.xxx.xxx 訂閱
非常感謝syntax大大的回覆 ^^

小弟會試試看滴..^^

===================引 用 syntax 文 章===================
只要是你自己宣告的,都必須在 FreeLibrary(ADllHandle); 前釋放
shine0989
一般會員


發表:9
回覆:31
積分:8
註冊:2008-06-21

發送簡訊給我
#9 引用回覆 回覆 發表時間:2010-05-12 11:36:40 IP:123.204.xxx.xxx 訂閱
真的真的非常感謝jow大大的回覆..
每次小弟遇到困難 jow 大大都會指點小弟..^^

小弟會努力試試看 jow大大所指點的程式碼..
真的很感謝..^^

===================引 用 jow 文 章===================
在每個ButtonClick動作中卸載DLL檔
可能會動到Child Form 的相關資源
即使用 {$R *.dfm} 連結的資源檔
Child Form 所佔記憶體結構將無法被描述
以上純屬推測, 請自行驗證...
所以你只能做到以下程度的動態載入
在FormCreate, FromClose載入及卸載DLL檔
以下程式碼供你參考
[code delphi]
unit fMain;

interface
uses
Windows, Classes,Forms, StdCtrls, Controls, ExtCtrls;

type
TGetChildForm = function(MDIMainForm: TForm; AClassName: string; var f: TForm): Boolean; safecall;

TfrmMain = class(TForm)
Panel1: TPanel;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
? public
??? h: THandle;
??? x: TGetChildForm;
? end;

var
? frmMain: TfrmMain;

implementation

{$R *.dfm}

procedure TfrmMain.FormCreate(Sender: TObject);
begin
? @x := nil;
? h := LoadLibrary('TestDll009.dll');
? if h > 0 then
? begin
??? @x := GetProcAddress(h,'GetChildForm');
? end;
end;

procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
? @x := nil;
? if h > 0 then
? begin
??? FreeLibraryAndExitThread(h,0);
? end;
end;

procedure TfrmMain.Button1Click(Sender: TObject);
var
? f: TForm;
begin
? if Assigned(x) and x(Self,'TfrmChild1',f) then
? begin
??? f.WindowState := wsNormal;
??? f.BringToFront;
? end;
end;

procedure TfrmMain.Button2Click(Sender: TObject);
var
? f: TForm;
begin
? if Assigned(x) and x(Self,'TfrmChild2',f) then
? begin
??? f.WindowState := wsNormal;
??? f.BringToFront;
? end;
end;

end.
[/code]
^_^
?
?
shine0989
一般會員


發表:9
回覆:31
積分:8
註冊:2008-06-21

發送簡訊給我
#10 引用回覆 回覆 發表時間:2010-05-12 13:14:40 IP:123.204.xxx.xxx 訂閱
請問 jow 大大...

小弟試著用大大的方式..
已功成開啟DLL的FORM了..
但是關掉第一個DLL後..
要再開第二個DLL...
就發生錯誤了..
錯誤訊息如下↓

A class named TfxDMPPage already exists.

小弟判斷..應該是小弟的這二個DLL..都含有Fastreport 4 的報表的關係..

請問 jow 大大
有什麼方式可以調用含有Fastreport 4的DLL呢???

在此感謝 ^^
shine0989
一般會員


發表:9
回覆:31
積分:8
註冊:2008-06-21

發送簡訊給我
#11 引用回覆 回覆 發表時間:2010-05-19 16:55:31 IP:123.204.xxx.xxx 訂閱
還是有那位先進知道能指點小弟嗎???


===================引 用 shine0989 文 章===================
請問 jow? 大大...

小弟試著用大大的方式..
已功成開啟DLL的FORM了..
但是關掉第一個DLL後..
要再開第二個DLL...
就發生錯誤了..
錯誤訊息如下↓

A class named TfxDMPPage already exists.

小弟判斷..應該是小弟的這二個DLL..都含有Fastreport 4 的報表的關係..

請問 jow? 大大
有什麼方式可以調用含有Fastreport 4的DLL呢???

在此感謝? ^^
系統時間:2024-05-02 6:57:38
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!