DLL CallBackFunction 的問題 |
缺席
|
wscken
初階會員 發表:28 回覆:75 積分:45 註冊:2003-08-05 發送簡訊給我 |
請問各位大大,有人使用過動態鏈結DLL檔案的CallBackFunction嗎? 這是書上的範例,
dll
--------------------------
Type
TFoundStrProc = procedure(StrPos: PChar); StdCall; function SearchStr(ASrcStr, ASearchStr: PChar; AProc: TFarProc): Integer; StdCall;
var
FindStr: PChar ;
begin
ShowMessage('接到參數值 ASrcStr=' String(ASrcStr) ' ASearchStr=' String(ASearchStr)) ; FindStr := ASrcStr ;
FindStr := StrPos(FindStr, ASearchStr) ;
while FindStr<>nil do
begin
if AProc<>nil then
TFoundStrProc(AProc)(FindStr) ;
FindStr := FindStr 1 ;
FindStr := StrPos(FindStr, ASearchStr) ;
end;
Result := 1 ; end ;
-----------------------------
第一種呼叫
-----------------------------
function SearchStr(ASrcStr, ASearchStr: PChar; AProc: TFarProc): Integer; StdCall; external 'StrSrchLib.dll' ; procedure StrPosProc(AStrPsn: PChar); StdCall;
begin
inc(Count) ;
end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:=caFree ;
Form1 := nil ;
end; procedure TForm1.btnCallDLLFuncClick(Sender: TObject);
var
S,S2: String ;
begin
Count := 0 ;
SetLength(S,memStr.GetTextLen) ;
memStr.GetTextBuf(PChar(S),memStr.GetTextLen) ;
S2 := edtSearchStr.Text ; SearchStr(PChar(S), PChar(S2), @StrPosProc) ; ShowMessage(Format('%s %s %d %s',[edtSearchStr.Text, 'occurs', Count, 'times.'])) ;
end; -----------------------------
第二種呼叫
-----------------------------
procedure StrPosProc(AStrPsn: PChar); StdCall;
begin
inc(Count) ;
end; procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:=caFree ;
Form2 := nil ;
end; procedure TForm2.btnCallDLLFuncClick(Sender: TObject);
type
TfncCnx = function (ASrcStr, ASearchStr: PChar; AProc: TFarProc): Integer;
var
S,S2: String ;
cnx : TfncCnx ;
DllName, FunName: String ;
LibHandle: THandle ;
begin
Count := 0 ;
SetLength(S,memStr.GetTextLen) ;
memStr.GetTextBuf(PChar(S),memStr.GetTextLen) ;
S2 := edtSearchStr.Text ; DllName:=ExtractFilePath(Application.ExeName) 'StrSrchLib.dll'; LibHandle := SafeLoadLibrary(DllName);
if LibHandle = 0 then showMessage('Can not load dynamic library ' DLLName ' !!')
else
begin
FunName := 'SearchStr' ;
@cnx := GetProcAddress(LibHandle, PChar(FunName));
if @cnx = nil then
ShowMessage ('無法呼叫函數:' FunName)
else
begin
cnx(PChar(S), PChar(S2), @StrPosProc);
end ;
ShowMessage(Format('%s %s %d %s',[edtSearchStr.Text, 'occurs', Count, 'times.'])) ;
end ;
end;
----------------------------- 當使用SafeLoadLibrary的時候,會發生接到的資料都無法辨識的問題,
這種問題有沒有解決的方法,還是DLL一定會這樣呢???
|
liorex
初階會員 發表:19 回覆:60 積分:32 註冊:2002-08-20 發送簡訊給我 |
你的程式我有幾個疑問
1.定義TFoundStrProc = procedure(StrPos: PChar); StdCall;
之後變成TFarProc ??是不是要將TFarProc 改為 TFoundStrProc
2.實作是
function SearchStr(ASrcStr, ASearchStr: PChar; AProc: TFarProc): Integer; StdCall;
但是call 的定義卻是
TfncCnx = function (ASrcStr, ASearchStr: PChar; AProc: TFarProc): Integer;
少了 stdcall;應該會有問題
修改一下看看 ----------------------
一切有為法 如夢幻泡影
如露亦如電 應做如是觀
----------------------
|
wscken
初階會員 發表:28 回覆:75 積分:45 註冊:2003-08-05 發送簡訊給我 |
liorex大大: 謝謝你 ^^ 第一點
TFoundStrProc = procedure(StrPos: PChar); StdCall;這個是定義在dll裡面的,
跟TfncCnx = function (ASrcStr, ASearchStr: PChar; AProc: TFarProc): Integer;的作用是一樣的,
至於你說的TFarProc,他會回傳的是一個指標,所以兩各是不相同的。 第二點
stdcall,確實是這個問題,因為沒有這個,所以傳入的指標在Dll中會看不懂,
所以,我把它加上去後,Dll就能抓到程式中的位址了,謝謝您 ^^
|
wuabc
初階會員 發表:6 回覆:60 積分:33 註冊:2002-10-28 發送簡訊給我 |
引言: liorex大大: 謝謝你 ^^ 第一點 TFoundStrProc = procedure(StrPos: PChar); StdCall;這個是定義在dll裡面的, 跟TfncCnx = function (ASrcStr, ASearchStr: PChar; AProc: TFarProc): Integer;的作用是一樣的, 至於你說的TFarProc,他會回傳的是一個指標,所以兩各是不相同的。TFarProc定義在Windows.pas 原文為 TFarProc = Pointer; |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |