dll 函式中宣告 string 本地變數,是否會產生問題? |
尚未結案
|
cancer
高階會員 發表:58 回覆:319 積分:190 註冊:2004-07-31 發送簡訊給我 |
各位大大, 我寫了一個 Dll 檔,裡面有一個函式,是給 InstallShield 在安裝
時驗證使用者輸入的序號用的。下面第一個函式是我經多次修改後才
能正確使用的函式,執行無誤,安裝過程很順利,就算使用者輸入錯
誤序號,安裝程式就給最多三次的機會,三次全錯,就停止安裝。 第二個函式是修改前的函式,當使用者輸入正確的序號,則安裝順利完成,
但如果輸入錯誤的序號,安裝程式立即報告 "The Called DLL was crashed"
的錯誤,並忽略剩下的重試機會,安裝過程就結束了。 在 InstallShield 裡面已設定六個輸入格,而且只能輸入數字。 正確執行的函式如下:
function ValidateSerial ( h : THandle ; a,b,c,d : PChar) : Integer; stdcall; begin // 序號為 543210 if (c[0] = '5') and (c[1] = '4') and (c[2] = '3') and (c[3] = '2') and (c[4] = '1') and (c[5] = '0') and (c[6] = #0) then result := 1 // 通過驗證 else result := -1; end不能正確執行的函式如下: function ValidateSerial ( h : THandle ; a,b,c,d : PChar) : Integer; stdcall; var s : string; begin s := c; if StrToInt(s) = 543210 then result := 1 else result := 0; end第二個函式宣告了一個 string 型態的變數,是不是這種 Delphi 專用的變數型態使得函式被其他 C/C 程式碼呼叫時會產生問題? 奇怪的是,函式若傳回 true 就沒問題,傳回 false 就連累整個 Dll 都 Crash 掉。 謝謝 |
leajean
一般會員 發表:1 回覆:3 積分:0 註冊:2005-01-24 發送簡訊給我 |
|
malanlk
尊榮會員 發表:20 回覆:694 積分:577 註冊:2004-04-19 發送簡訊給我 |
|
cancer
高階會員 發表:58 回覆:319 積分:190 註冊:2004-07-31 發送簡訊給我 |
不好意思,打錯字啦。因為我一開始設計時,傳回值以 1 為成功,
2 為失敗,為了讓各位不會多想我為甚麼會選擇傳回 2,於是我想把它
改成-1,結果一時弄錯,變成 0。
所以,第二個函式失敗時是傳回 2,不是 0。 失敗的函式應是如此:
function ValidateSerial ( h : THandle ; a,b,c,d : PChar) : Integer; stdcall; var s : string; begin s := c; if StrToInt(s) = 543210 then result := 1 else result := 2; end但其實傳回 0 跟傳回 2 都不應該使整個 dll crash 掉。但反而是傳回 1 的話,一切就正常。 另外最重要最重要的是,為了找出真正原因,我在第一個函式中宣告一個 string變數,但我沒有使用它,於是同樣的問題又出現了,亦即只要傳回 值不是 1,dll就 crash 掉。再把 var s : string 拿掉,不傳回 1 , 也能正常運作。我又試過宣告一個整數,同樣不使用它,卻又不會有這個 問題,所以,這個問題跟那個 var s : string; 應該關係重大,因為 InstallShield 所提供的範例是用 C ,而且肯定一點是,InstallShield 用 C 程式碼來呼叫我的 dll 函式。 |
malanlk
尊榮會員 發表:20 回覆:694 積分:577 註冊:2004-04-19 發送簡訊給我 |
|
adonis
高階會員 發表:140 回覆:258 積分:159 註冊:2002-04-15 發送簡訊給我 |
cancer, 您好 s:=c; <-- 建議改成 s:=strpas(c); Help - StrPas: Converts null-terminated string to a Pascal string. 至於~
引言: 另外最重要最重要的是,為了找出真正原因,我在第一個函式中宣告一個 string變數,但我沒有使用它,於是同樣的問題又出現了,亦即只要傳回 值不是 1,dll就 crash 掉。再把 var s : string 拿掉,不傳回 1 , 也能正常運作。我又試過宣告一個整數,同樣不使用它,卻又不會有這個 問題,所以,這個問題跟那個 var s : string; 應該關係重大這個問題我之前也有碰過,情形和你一樣,但唯一的不同是我的函數還有去調用其他函數,是在後段因 String 形態的相關問題所致。但後來發現只要有正確的調用 String & PChar 之間的轉換大致上是沒有問題的。 我也在學習中,若回應不當請見諒 ~ 發表人 - adonis 於 2005/09/01 09:59:32
------
我也在努力學習中,若有錯謬請見諒。 |
cancer
高階會員 發表:58 回覆:319 積分:190 註冊:2004-07-31 發送簡訊給我 |
|
malanlk
尊榮會員 發表:20 回覆:694 積分:577 註冊:2004-04-19 發送簡訊給我 |
|
adonis
高階會員 發表:140 回覆:258 積分:159 註冊:2002-04-15 發送簡訊給我 |
Dear All 基本上應該是在 export 出來的介面窗口盡可能不要去使用String型態而改用PChar應該就沒問題才是(就String資料型態而言)
Help-
引言: { Important note about DLL memory management: ShareMem must be the first unit in your library's USES clause AND your project's (select Project-View Source) USES clause if your DLL exports any procedures or functions that pass strings as parameters or function results. This applies to all strings passed to and from your DLL--even those that are nested in records and classes. ShareMem is the interface unit to the BORLNDMM.DLL shared memory manager, which must be deployed along with your DLL. To avoid using BORLNDMM.DLL, pass string information using PChar or ShortString parameters. }雖然S := c; 在 delphi 中是合法的,能通過編譯,也能正確執行,因為 Delphi 會自動進行轉換。但我還是建議在DLL中使用 StrPas 來StrPas: Converts null-terminated string to a Pascal string.會比較安全一點。 以上是我的一些看法,如有錯謬請見諒 ~ 因為我也正在學習中。
------
我也在努力學習中,若有錯謬請見諒。 |
cancer
高階會員 發表:58 回覆:319 積分:190 註冊:2004-07-31 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |