呼叫DLL時發生記憶體錯誤,一個很怪的問題 |
答題得分者是:jow
|
cliffdean
一般會員 發表:9 回覆:14 積分:4 註冊:2004-12-07 發送簡訊給我 |
1.DLL裡面是這樣:
----------------------------------------------------------
function GetRegValue(regName: String):PChar; stdcall;
var reg : TRegistry;
begin
reg := TRegistry.Create;
try
result := PChar('');
reg.RootKey:=HKEY_CURRENT_USER;
if reg.OpenKey('\Software\msoft',True) then
begin
result := PChar(reg.ReadString(regName));
end;
finally
reg.CloseKey;
reg.Free;
end;
end;
-----------------------------------------------------------
宣告的時候是
-----------------------------------------------------------
function GetRegValue(regName:string):PChar;stdcall; external 'functions.dll';
-----------------------------------------------------------
結果假設我的註冊檔中某個變數的值是mylove結果每次呼叫GetRegValue的結果都不太一樣,有的時候會正常,有的時候會變成mylo後面的ve不見了。 另一個問題也是在呼叫DLL的時候發生的......
在DLL裡面是這樣
-------------------------------------------------------------
function GetInsertTime(conn : TADOConnection ) : Pchar ;stdcall;export;
var qryGetTime : TADOQuery;
var strTmp : string;
begin
qryGetTime := TADOQUERY.Create(Application);
qryGetTime.Connection := conn;
qryGetTime.SQL.Clear();
qryGetTime.SQL.Add('SELECT NOW()');
qryGetTime.Open();
strTmp:= FormatDateTime('yyyy-mm-dd hh:nn:ss',qryGetTime.Fields[0].AsDateTime);
result := Pchar(strTmp);
qryGetTime.Free();
end;
----------------------------------------------------------
因為呼叫這支程式的時候是同一個DLL裡面的不同unit所以引用時是這樣寫的
implementation
uses Undllsystem,Undllreg;
而我在下面呼叫GetInsertTime的時候,如果再呼叫前先隨便ShowMessage一個訊息再呼叫就會正常,而一把Showmessage拿掉,程式就會出錯,錯誤訊息是access violation as address .....
但是上面兩個函數在別的地方呼叫又都正常,應該不是函數的問題,我猜想應該是記憶體的問題,請高手指導一下,謝謝!
|
jow
尊榮會員 發表:66 回覆:751 積分:1253 註冊:2002-03-13 發送簡訊給我 |
------------------- 幫忙重貼程式碼. 我覺得你在DLL中用的資料型態應多斟酌.除非你用的式BPL. 引言上標記紅色部分,我認為用在DLL中並不適當.引言: 1.DLL裡面是這樣: ---------------------------------------------------------- function GetRegValue(regName: String):PChar; stdcall; var reg : TRegistry; begin reg := TRegistry.Create; try result := PChar('');//多的 reg.RootKey:=HKEY_CURRENT_USER; if reg.OpenKey('\Software\msoft',True) then begin result := PChar(reg.ReadString(regName)); end; finally reg.CloseKey; reg.Free; end; end; ----------------------------------------------------------- 宣告的時候是 ----------------------------------------------------------- function GetRegValue(regName:string):PChar;stdcall; external 'functions.dll'; ----------------------------------------------------------- 結果假設我的註冊檔中某個變數的值是mylove結果每次呼叫GetRegValue的結果都不太一樣,有的時候會正常,有的時候會變成mylo後面的ve不見了。 另一個問題也是在呼叫DLL的時候發生的...... 在DLL裡面是這樣 ------------------------------------------------------------- function GetInsertTime(conn : TADOConnection ) : Pchar ;stdcall;export; var qryGetTime : TADOQuery; var strTmp : string; begin qryGetTime := TADOQUERY.Create(Application); qryGetTime.Connection := conn; qryGetTime.SQL.Clear(); qryGetTime.SQL.Add('SELECT NOW()'); qryGetTime.Open(); strTmp:= FormatDateTime('yyyy-mm-dd hh:nn:ss',qryGetTime.Fields[0].AsDateTime); result := Pchar(strTmp); qryGetTime.Free(); end; ---------------------------------------------------------- 因為呼叫這支程式的時候是同一個DLL裡面的不同unit所以引用時是這樣寫的 implementation uses Undllsystem,Undllreg; 而我在下面呼叫GetInsertTime的時候,如果再呼叫前先隨便ShowMessage一個訊息再呼叫就會正常,而一把Showmessage拿掉,程式就會出錯,錯誤訊息是access violation as address ..... 但是上面兩個函數在別的地方呼叫又都正常,應該不是函數的問題,我猜想應該是記憶體的問題,請高手指導一下,謝謝! |
cliffdean
一般會員 發表:9 回覆:14 積分:4 註冊:2004-12-07 發送簡訊給我 |
|
jow
尊榮會員 發表:66 回覆:751 積分:1253 註冊:2002-03-13 發送簡訊給我 |
你好,因為一般的DLL檔來說,你不能預期它是使用
Delphi來做為開發工具,所以如果你是開發通用性
質的DLL,那麼在使用資料型別上就要考慮到相容
性的問題,Delphi中特有的資料型別以及VCL類別,
基本上是不具相容性的. 而bpl檔則是Delphi特定格式的Library檔案,你可
以用下方式開啟一個新的Borland Package 專案
File->New->Other->(New Page)下選擇 Package項目
之後你可以將你的檔案Add到這裡來,程式的寫法如同
一般專案的開發,並且其中也可以包含元件的開發. Package 專案經過編譯連結後產生 *.bpl形式的檔案,
其實它就是DLL檔了. 在這裡任何Delphi資料型態都可使用,基本上是沒有限制的. 至於 Global Application Object寫入DLL檔案中,
基本上你要先確定,它真的存在,例如非Application的專
案Call到你的Function 時會有何狀況?
最後語法上的邏輯有些盲點:
function GetInsertTime(conn : TADOConnection ) : Pchar ;stdcall;export; var qryGetTime : TADOQuery; var strTmp : string; begin (1)qryGetTime := TADOQUERY.Create(Application); (2)qryGetTime.Connection := conn; [red]///// Application 有沒有可能不存在? [red]///// 步驟(1)產生的物件會造成記憶體遺漏. ... end; |
jow
尊榮會員 發表:66 回覆:751 積分:1253 註冊:2002-03-13 發送簡訊給我 |
|
jow
尊榮會員 發表:66 回覆:751 積分:1253 註冊:2002-03-13 發送簡訊給我 |
|
cliffdean
一般會員 發表:9 回覆:14 積分:4 註冊:2004-12-07 發送簡訊給我 |
|
jow
尊榮會員 發表:66 回覆:751 積分:1253 註冊:2002-03-13 發送簡訊給我 |
|
cliffdean
一般會員 發表:9 回覆:14 積分:4 註冊:2004-12-07 發送簡訊給我 |
|
jow
尊榮會員 發表:66 回覆:751 積分:1253 註冊:2002-03-13 發送簡訊給我 |
測試看看,是否因為Connection尚未完成;
function GetInsertTime(conn : TADOConnection ) : Pchar ;stdcall;export; var qryGetTime : TADOQuery; strTmp : string; Timeout: Cardinal; begin qryGetTime := TADOQUERY.Create(Application); try qryGetTime.Connection := conn; qryGetTime.SQL.Clear(); qryGetTime.SQL.Add('SELECT NOW()'); Timeout := GetTickCount 10000; //設定Timeout = 10秒 qryGetTime.Open(); while not qryGetTime.Active and (GetTickCount |
cliffdean
一般會員 發表:9 回覆:14 積分:4 註冊:2004-12-07 發送簡訊給我 |
|
jow
尊榮會員 發表:66 回覆:751 積分:1253 註冊:2002-03-13 發送簡訊給我 |
|
cliffdean
一般會員 發表:9 回覆:14 積分:4 註冊:2004-12-07 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |