線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:5621
推到 Plurk!
推到 Facebook!

Loadlibrary 特定Dll 時會發生錯誤 !!

缺席
TTS
初階會員


發表:72
回覆:66
積分:27
註冊:2003-05-06

發送簡訊給我
#1 引用回覆 回覆 發表時間:2008-03-05 01:45:09 IP:202.86.xxx.xxx 訂閱
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';


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 下
附加檔案:47cd8aa5e29bc_Dll.rar
編輯記錄
TTS 重新編輯於 2008-03-05 01:45:37, 註解 無‧
TTS 重新編輯於 2008-03-05 01:47:20, 註解 無‧
TTS 重新編輯於 2008-03-05 10:27:46, 註解 無‧
change.jian
版主


發表:29
回覆:620
積分:439
註冊:2003-06-02

發送簡訊給我
#2 引用回覆 回覆 發表時間:2008-03-05 10:58:23 IP:211.23.xxx.xxx 訂閱
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

發送簡訊給我
#3 引用回覆 回覆 發表時間:2008-03-05 13:57:06 IP:202.175.xxx.xxx 訂閱
版主你好:

我把程式改為:
[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=
編輯記錄
TTS 重新編輯於 2008-03-05 14:02:05, 註解 無‧
TTS 重新編輯於 2008-03-05 16:13:51, 註解 無‧
TTS 重新編輯於 2008-03-05 16:13:51, 註解 無‧
TTS 重新編輯於 2008-03-05 16:16:58, 註解 無‧
TTS 重新編輯於 2008-03-05 16:25:32, 註解 無‧
Coffee
版主


發表:31
回覆:878
積分:561
註冊:2006-11-15

發送簡訊給我
#4 引用回覆 回覆 發表時間:2008-03-05 14:42:19 IP:220.130.xxx.xxx 訂閱
請發文者使用程式碼區塊發表程式內文
------
不論是否我發的文,在能力範圍皆很樂意為大家回答問題。
為了補我的能力不足之處,以及讓答案可以被重複的使用,希望大家能儘量以公開的方式問問題。
在引述到我的文時自然會儘量替各位想辦法,謝謝大家!
change.jian
版主


發表:29
回覆:620
積分:439
註冊:2003-06-02

發送簡訊給我
#5 引用回覆 回覆 發表時間:2008-03-05 22:10:25 IP:61.62.xxx.xxx 訂閱
TTS:

1.可否把你的 code 壓縮一下,放上來,我幫你看.你附的 dll 檔是可以載入的
2.補充說明一點, dll 檔不一定要放在 system32 目錄下,也可以跟執行檔同一個目錄下,一樣可以執行.除非像 midas.dll 在第一次執行時會去跟系統註冊,此後就只記得這個路徑,或者有其他程式也要共用,那麼才需要放 system32 下.依你的問題描述,不應該有這個狀況發生.
TTS
初階會員


發表:72
回覆:66
積分:27
註冊:2003-05-06

發送簡訊給我
#6 引用回覆 回覆 發表時間:2008-03-05 22:53:56 IP:202.86.xxx.xxx 訂閱

[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 重新編輯於 2008-03-05 22:57:35, 註解 無‧
TTS 重新編輯於 2008-03-05 23:00:22, 註解 無‧
TTS 重新編輯於 2008-03-05 23:02:56, 註解 無‧
TTS 重新編輯於 2008-03-06 00:28:28, 註解 無‧
TTS
初階會員


發表:72
回覆:66
積分:27
註冊:2003-05-06

發送簡訊給我
#7 引用回覆 回覆 發表時間:2008-03-06 01:05:01 IP:202.86.xxx.xxx 訂閱
[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=

編輯記錄
TTS 重新編輯於 2008-03-06 01:07:01, 註解 無‧
TTS 重新編輯於 2008-03-06 01:13:51, 註解 無‧
TTS 重新編輯於 2008-03-06 01:23:51, 註解 無‧
TTS 重新編輯於 2008-03-06 01:26:04, 註解 無‧
change.jian
版主


發表:29
回覆:620
積分:439
註冊:2003-06-02

發送簡訊給我
#8 引用回覆 回覆 發表時間:2008-03-06 10:36:14 IP:211.23.xxx.xxx 訂閱
TTS:

從下面這個描述,看起來是你的 dll 的問題,你有確認你的 dll 是可用的嗎?
1.我發現0xc0000005的錯誤是發生當程式使用"靜態使用"這段程式碼時就會一Run就出現錯誤訊息(也就是一用到該DLL的function)
2.但是當使用"動態使用"這段程式碼時 在第一個showMessage可以抓到訊息為: 'IC卡相關DLL檔載入失敗: 記憶體位置存取不正確


PS:靜態使用,表示程式一開始載入時同時載入 dll 檔,動態載入,是指到 LoadLibrary 時才載入該 dll 檔.
TTS
初階會員


發表:72
回覆:66
積分:27
註冊:2003-05-06

發送簡訊給我
#9 引用回覆 回覆 發表時間:2008-03-06 14:28:45 IP:202.175.xxx.xxx 訂閱
不知版大 您是否試著使用過此dll , 是否也會發生相同情形???
change.jian
版主


發表:29
回覆:620
積分:439
註冊:2003-06-02

發送簡訊給我
#10 引用回覆 回覆 發表時間:2008-03-07 12:13:58 IP:211.23.xxx.xxx 訂閱

先前測試時,我就有試過載入 dll 了,除了 dsimeid_c1.dll 會需要 vcl60.bpl 之外,另外兩個都可以正常載入
(可以看我 2 樓的回答)
===================引 用 TTS 文 章===================
不知版大 您是否試著使用過此dll , 是否也會發生相同情形???
TTS
初階會員


發表:72
回覆:66
積分:27
註冊:2003-05-06

發送簡訊給我
#11 引用回覆 回覆 發表時間:2008-03-07 14:26:19 IP:202.175.xxx.xxx 訂閱
版大好
小弟此程式最主要是要使用'dsimeid_c1.dll', 而CG32.dll & CC3260MT.dll 都是因為載入時依錯誤訊息 而另外再載入的.
所以必須要能成功使用'dsimeid_c1.dll' 及其function才是我要的結果!!

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