Loadlibrary 特定Dll 時會發生錯誤 !! |
缺席
|
TTS
初階會員 發表:72 回覆:66 積分:27 註冊:2003-05-06 發送簡訊給我 |
function ICCard_Data(ValIndData: Integer;RefDCData: PChar;Refdclength: PInteger): LongInt; stdcall; external 'dsimeid_c1.dll' name 'DSI_Get_Data'; function ICCard_Off: LongInt; stdcall; external 'dsimeid_c1.dll' name 'DSI_Card_Off'; procedure TForm1.BitBtn2Click(Sender: TObject); var hCG32, hCC3260MT: THandle; hModal: Thandle; begin try hModal:= LoadLibrary('dsimeid_c1.dll'); //hCG32:= LoadLibrary('CG32.dll'); //hCC3260MT:= LoadLibrary('CC3260MT.dll'); if hModal = 0 then ShowMessage('DLL檔載入失敗 !!') else begin ShowMessage(IntToStr(hModal)); end; finally //FreeLibrary(hCC3260MT); //FreeLibrary(hCG32); FreeLibrary(hModal); end; 如上Src, 1.當執行紅色段程式時會跳出錯誤訊息: " 無法找到找到動態連結程式庫 CG32.DLL". 2.於是上網尋找CG32.DLL並將檔案Copy至 C:\WINDOWS\System32 下, 此次執行程式時先將藍色段的mark拿掉, 執行至紅色段時會跳出錯誤誤訊息: '' 無法找到找到動態連結程式庫 CC3260MT.DLL". 3.再次上網尋找CC3260MT.DLL並將檔案Copy至 C:\WINDOWS\System32 下, 此次執行程式時先將綠色段的mark拿掉, 執行至綠色段時會跳出錯誤誤訊息: Two different CRTLDLLs are loaded. CG might report false errors (C:\WINDOWS\System32\CC3260MT.DLL) (C:\WINDOWS\System32\CC3260MT.dll) 4.而最後當要把程式關閉(Close)時 又出現一個訊息: 'CodeGuard detected error(s) in the program. A log file will be created' 是否可以提供小弟解決方式!! =Tks= end; ps: 作業系統為XP, 安裝Delphi 6 (無C 環境), 且此dsimeid_c1.dll 只能於XP系統使用, 檔案置於C:\WINDOWS\System32 下 | |
change.jian
版主 發表:29 回覆:620 積分:439 註冊:2003-06-02 發送簡訊給我 |
1.LoadLibrary 為動態載入 dll 的做法,而 function ICCard_Get: LongInt; stdcall; .... 是靜態載入的做法,兩者最大差別是動態是程式執行到 LoadLibrary 才會把該 dll 載入, 而靜態則是程式一啟動就載入了.理論上應該是不可以對同一個 dll 又動態又靜態載入的
2.我把 上面的宣告拿掉,其實是可以載入的,除了 dsimeid_c1.dll 這個之外,原因是這個 dll 還有用到其他的檔案 (vcl60.bpl) 給你我的 source code ,你試試看 [code delphi] //function ICCard_Get: LongInt; stdcall; external 'dsimeid_c1.dll' name 'DCI_Get_Card'; //function ICCard_Data(ValIndData: Integer;RefDCData: PChar;Refdclength: PInteger): LongInt; stdcall; external 'dsimeid_c1.dll' name 'DSI_Get_Data'; //function ICCard_Off: LongInt; stdcall; external 'dsimeid_c1.dll' name 'DSI_Card_Off'; function GetErrorstring: string; var lz: Cardinal; err: array[0..512] of Char; begin lz := GetLastError; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nil, lz, 0, @err, 512, nil); Result := string(err); end; procedure TForm1.BitBtn1Click(Sender: TObject); var hCG32, hCC3260MT: THandle; hModal: Thandle; begin try hModal:= LoadLibrary('dsimeid_c1.dll'); //hCG32:= LoadLibrary('CG32.dll'); //hCC3260MT:= LoadLibrary('CC3260MT.dll'); if hModal = 0 then ShowMessage('DLL檔載入失敗:' GetErrorstring) else begin ShowMessage(IntToStr(hModal)); end; finally //FreeLibrary(hCC3260MT); //FreeLibrary(hCG32); FreeLibrary(hModal); end; end; [/code] |
|
TTS
初階會員 發表:72 回覆:66 積分:27 註冊:2003-05-06 發送簡訊給我 |
版主你好:
我把程式改為: [code delphi] //function ICCard_Get(): Integer; stdcall; external 'dsimeid_c1.dll' name 'DSI_Get_Card'; //function ICCard_Data(BufLen: PInteger;RefDCData: PByte;Refdclength: PInteger): Integer; stdcall; external 'dsimeid_c1.dll' name 'DSI_Get_Data'; //function ICCard_Off(): Integer; stdcall; external 'dsimeid_c1.dll' name 'DSI_Card_Off'; procedure TForm1.BitBtn2Click(Sender: TObject); var hCG32, hCC3260MT: THandle; hModal: THandle; iLen: Integer; Buffer: String; begin try hCC3260MT:= LoadLibrary('CC3260MT.dll'); hModal:= LoadLibrary('dsimeid_c1.dll'); hCG32:= LoadLibrary('CG32.dll'); if hModal = 0 then ShowMessage('DLL檔載入失敗: ' GetErrorstring) else begin ShowMessage(IntToStr(hModal)); //iLen:= Sizeof(Buffer); //rtn:= ICCard_Get; //Buffer:= ''; //rtn:= ICCard_Data(PInteger(1), PByte(@Buffer), @iLen); //Edit1.Text:= Trim(Buffer); end; finally FreeLibrary(hCC3260MT); FreeLibrary(hCG32); FreeLibrary(hModal); end; end; [/code] 1.下面Mark段先不執行下 單純Load Dll的狀況: 每次Run程式的第一次執行總是會有訊息"DLL檔載入失敗: 參數錯誤" 但是程式不離開下Btn再按下去 卻又可以抓到hModal 2.程式下面Mark拿掉 如果不宣告最上面的function 的話 則程式會找不到ICCard_Get 及 ICCard_Data 3.3個宣告 & 程式下面Mark皆拿掉(全部執行) , Run下去後還沒到專案檔的begin就會先出現錯誤訊息2次: "應用程式正常初始(0x0000005) 失敗. 請按一下[確定]終止應用程式" 但是確定後程式還是可以開啟, 且後面的程式也都可以正常Run出結果! 4.小弟此程式最主要是要使用'dsimeid_c1.dll', 而CG32.dll & CC3260MT.dll 都是因為載入時依錯誤訊息 而另外再載入的. 還望版主再提供建議 =Tks= |
|
Coffee
版主 發表:31 回覆:878 積分:561 註冊:2006-11-15 發送簡訊給我 |
||
change.jian
版主 發表:29 回覆:620 積分:439 註冊:2003-06-02 發送簡訊給我 |
||
TTS
初階會員 發表:72 回覆:66 積分:27 註冊:2003-05-06 發送簡訊給我 |
[code delphi] unit dllICCards; interface uses Windows, SysUtils, Controls, UnSysUtils; function ICCard_Get: Integer; stdcall; external 'dsimeid_c1.dll' name 'DSI_Get_Card'; function ICCard_Data(BufLen: PInteger;RefDCData: PByte;Refdclength: PInteger): Integer; stdcall; external 'dsimeid_c1.dll' name 'DSI_Get_Data'; function ICCard_Off: Integer; stdcall; external 'dsimeid_c1.dll' name 'DSI_Card_Off'; //讀IC卡資料, 回傳值為錯誤訊息, 空值為正確讀取 function GetICCardData(var ICChiName, ICEngName, ICSex, ICIDNo: String;var ICBirthDay: TDate): String; implementation function GetICCardData(var ICChiName, ICEngName, ICSex, ICIDNo: String;var ICBirthDay: TDate): String; var hModal, hCG32, hCC3260MT: THandle; sRtn, iLen: Integer; Buffer: String; begin Result:= ''; ICChiName:= ''; ICEngName:= ''; ICSex:= ''; ICIDNo:= ''; ICBirthDay:= 0; try hCC3260MT:= LoadLibrary('CC3260MT.dll'); hModal:= LoadLibrary('dsimeid_c1.dll'); hCG32:= LoadLibrary('CG32.dll'); if hModal = 0 then Result:= 'IC卡相關DLL檔載入失敗: ' GetErrorstring ' !!' else begin iLen:= Sizeof(Buffer); //mark1 sRtn:= ICCard_Get; Buffer:= ''; sRtn:= ICCard_Data(PInteger(1), PByte(@Buffer), @iLen); Buffer:= StringReplace(Trim(Buffer), ',', '', [rfReplaceAll]); Buffer:= StringReplace(Trim(Buffer), ',', '', [rfReplaceAll]); Buffer:= StringReplace(Trim(Buffer), ' ', '', [rfReplaceAll]); Buffer:= StringReplace(Trim(Buffer), ' ', '', [rfReplaceAll]); Buffer:= StringReplace(Trim(Buffer), Char(StrToInt('$' '140')), '', [rfReplaceAll]); ICChiName:= Trim(Buffer); Buffer:= ''; sRtn:= ICCard_Data(PInteger(3), PByte(@Buffer), @iLen); Buffer:= StringReplace(Trim(Buffer), ',', '', [rfReplaceAll]); ICEngName:= Trim(Buffer); Buffer:= ''; sRtn:= ICCard_Data(PInteger(6), PByte(@Buffer), @iLen); ICBirthDay:= StrToDate(Trim(Buffer), _iYearLen); Buffer:= ''; sRtn:= ICCard_Data(PInteger(8), PByte(@Buffer), @iLen); if Trim(Buffer) = 'M' then ICSex:= '男' else if Trim(Buffer) = 'F' then ICSex:= '女' else ICSex:= '空'; Buffer:= ''; sRtn:= ICCard_Data(PInteger(21), PByte(@Buffer), @iLen); ICIDNo:= Copy(Trim(Buffer), 1, 7) '(' Copy(Trim(Buffer), 8, 1) ')'; sRtn:= ICCard_Off; //mark1 end; finally if hCC3260MT <> 0 then FreeLibrary(hCC3260MT); if hCG32 <> 0 then FreeLibrary(hCG32); if hModal <> 0 then FreeLibrary(hModal); end; end; end. [/code] 以上是我的Soruce Code 1.目前的狀況為GetICCardData要是有 mark1至mark1 的程式段, 在Run的開始(專案檔還沒到begin)就會出現: 應用程式正常初始(0xc0000005)失敗。請案一下﹝確定﹞終止應用程式。" 且會出現兩次, 按確定後還是繼續成功的Run出來, 不過要是單執行exe檔, 0xc0000005的錯誤還是會出來, 但此時的程式並無法Run成功 2.要是mark1至mark1 不執行(其實只要程式有效段包含'dsimeid_c1.dll' 的function) 就不會有0xc0000005的錯誤並可以正常執行. 3.我的電腦上只有Delphi的編譯程式, 有看過有裝VB的電腦 load dsimeid_c1.dll 時不會需要CG32.dll & CC3260MT.dll, 且也不會有0xc0000005的錯誤 |
|
TTS
初階會員 發表:72 回覆:66 積分:27 註冊:2003-05-06 發送簡訊給我 |
[code delphi]
unit UnDllLinks; interface uses Windows, Messages, Controls, Classes, Forms, SysUtils, Types, StdCtrls, Dialogs; function ICCard_Get(): Integer; stdcall; external 'dsimeid_c1.dll' name 'DSI_Get_Card'; function ICCard_Data(BufLen: PInteger;RefDCData: PByte;Refdclength: PInteger): Integer; stdcall; external 'dsimeid_c1.dll' name 'DSI_Get_Data'; function ICCard_Off(): Integer; stdcall; external 'dsimeid_c1.dll' name 'DSI_Card_Off'; implementation end. [/code] [code delphi] unit fmConnects; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons, UnDllLinks; type TForm1 = class(TForm) BitBtn1: TBitBtn; Edit1: TEdit; BitBtn2: TBitBtn; Edit2: TEdit; Memo1: TMemo; Edit3: TEdit; Edit4: TEdit; Edit5: TEdit; Label1: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel; Label5: TLabel; procedure BitBtn2Click(Sender: TObject); private { Private declarations } function GetICCardData(var ICChiName, ICEngName, ICSex, ICIDNo: String;var ICBirthDay: TDate): String; public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} function TForm1.GetICCardData(var ICChiName, ICEngName, ICSex, ICIDNo: String;var ICBirthDay: TDate): String; type TfncCnx = function (i : Integer) : THandle; var hCG32, hCC3260MT: THandle; hModal: THandle; rtn: Integer; iLen: Integer; Buffer: String; fun1, fun2, fun3: TfncCnx; function GetErrorstring: string; var lz: Cardinal; err: Array[0..512] of Char; begin lz:= GetLastError; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nil, lz, 0, @err, 512, nil); Result:= String(err); end; begin //靜態使用 iLen:= Sizeof(Buffer); rtn:= ICCard_Get; Buffer:= ''; rtn:= ICCard_Data(PInteger(21), PByte(@Buffer), @iLen); ICIDNo:= Trim(Buffer); //動態使用 //hCC3260MT:= LoadLibrary('CC3260MT.dll'); hModal:= LoadLibrary('dsimeid_c1.dll'); //hCG32:= LoadLibrary('CG32.dll'); try if hModal = 0 then ShowMessage('IC卡相關DLL檔載入失敗: ' GetErrorstring) else begin @fun1:= GetProcAddress(hModal, PChar('DSI_Get_Card')); @fun2:= GetProcAddress(hModal, PChar('DSI_Get_Data')); @fun3:= GetProcAddress(hModal, PChar('DSI_Card_Off')); if @fun2 = nil then begin ShowMessage ('無法呼叫函數: DSI_Get_Data'); end else if @fun3 = nil then begin ShowMessage ('無法呼叫函數: DSI_Card_Off'); end else if @fun1 = nil then begin ShowMessage ('無法呼叫函數: DSI_Get_Card'); end else begin rtn:= fun1(1); end; end; finally FreeLibrary(hModal); end; end; procedure TForm1.BitBtn2Click(Sender: TObject); var sErrStr: String; sChiName, sEngName, sSex, sIDNo: String; dtBirthDay: TDate; begin sErrStr:= GetICCardData(sChiName, sEngName, sSex, sIDNo, dtBirthDay); end; end. [/code] 以上為我重新試驗過後的Source Code 1.我發現0xc0000005的錯誤是發生當程式使用"靜態使用"這段程式碼時就會一Run就出現錯誤訊息(也就是一用到該DLL的function) 2.但是當使用"動態使用"這段程式碼時 在第一個showMessage可以抓到訊息為: 'IC卡相關DLL檔載入失敗: 記憶體位置存取不正確 3.要是讓程式同時執行靜態及動態段程式碼, 雖然會有0xc0000005的錯誤, 但是在動態使用時卻可以成功LoadLibrary進來, 但是最後Run到 FreeLibrary時 Btn第一次On Click時會出現Access violation at address 40006834 in module 'rtl60.bpl'. Read of address 0180FFFC. 但是第二次之後再On Click都不會有錯誤 !! 不知道要怎樣修正才能完全沒有錯誤的Run成功, 還望各位高手提供意見 !! =Tks= |
|
change.jian
版主 發表:29 回覆:620 積分:439 註冊:2003-06-02 發送簡訊給我 |
TTS:
從下面這個描述,看起來是你的 dll 的問題,你有確認你的 dll 是可用的嗎? 1.我發現0xc0000005的錯誤是發生當程式使用"靜態使用"這段程式碼時就會一Run就出現錯誤訊息(也就是一用到該DLL的function) 2.但是當使用"動態使用"這段程式碼時 在第一個showMessage可以抓到訊息為: 'IC卡相關DLL檔載入失敗: 記憶體位置存取不正確 PS:靜態使用,表示程式一開始載入時同時載入 dll 檔,動態載入,是指到 LoadLibrary 時才載入該 dll 檔. |
|
TTS
初階會員 發表:72 回覆:66 積分:27 註冊:2003-05-06 發送簡訊給我 |
||
change.jian
版主 發表:29 回覆:620 積分:439 註冊:2003-06-02 發送簡訊給我 |
||
TTS
初階會員 發表:72 回覆:66 積分:27 註冊:2003-05-06 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |