由於最近公司太忙,好久沒有更新我的BLOG了。原來想着寫寫關於HOOK驅動的文章,可是最后想想好久已經沒有做驅動的東西了,怕寫出來有錯誤,於是作罷。開發游戲也有一段時間了,發現使用DELPHI來開發網絡游戲不了解DELPHI下指針的使用是完全不行的。所以今天我簡單總結以下我使用DELPHI指針的心得。希望對大家有所幫助。
記得在大學學習C語言的時候在譚浩強編寫的書中,關於指針一章的開始就說“指針是C語言的精華”,可見指針對於C語言的重要性。其實在Pascal語言中指針也占據着重要的位置。
1:指針的賦值。
type
RTestInfo = record
Age:Integer;
end;
PtestInfo = ^ RtestInfo;
var
Test1,Test2:PtestInfo;
Begin
New(Test1);
New(Test2);
Test1^.Age:=12;
Test2:=Test1;
Application.MessageBox(Pchar(IntToStr(Test2^.Age)),’測試’,MB_OK);
Test1^.Age:=13;
Application.MessageBox(Pchar(IntToStr(Test2^.Age)),’測試’,MB_OK);
DisPose(Test1);
DisPose(Test2);
End;
上面的代碼中使用了Test2:=Test1;進行指針的賦值,也就是說進行賦值以后兩個變量指向的相同的地址,所以當Test1的Age發送變化以后Test2的Age也隨之發生了變化。反過來也是一樣。那如果我們要將Test1中的內容放在Test2中並且當Test1中的內容發生變化的時候Test2的內容不會發生變化有如何來做呢?其實很簡單,使用Test2^:=Test1^;就可以了,這個時候變量Test1和變量Test2指向的是兩個不同的地址,當一方的內容發生變化的時候另外一方不會受到影響。
2:數組和指針的轉換。
曾使用過API函數來編寫網絡通信的都知道,網絡傳輸過程中傳輸的都是char類型的數組。而我們經常需要將自己定義的一個結構通過網絡傳輸出去,並且當對方接收到這個數據以后又能將其轉換為相應的結構來處理。以前我是使用添加標記位來解決這個問題。其實使用數組和指針轉換是很簡單的。
type
RtestInfo = record
Age:Integer;
End;
Var
Test: RtestInfo;
Data:array[0..1024] of Char;
Begin
Test.Age:=13;
Fillchar(Data,SizeOf(Data),#0);
StrMove(Data,@ Test,sizeof(Test));
//數據發送
End;
在上面的例子中首先我們將我們定義數組Data清空,然后使用函數StrMove將結構Test的內容復制到Data中去。這個時候就可以將數據發送出去。當對方接受到數據以后,可以用以下的代碼進行還原。
type
RtestInfo = record
Age:Integer;
End;
Var
Test: RtestInfo;
Begin
StrMove(@Test,Data,sizeof(Test));
//處理數據
End;
這個時候就可以對發送過來的數據進行相應的處理了。
3:函數指針的使用。
在分模塊開發的過程中,DLL占據着重要的位置。在我開發游戲的服務端也是使用DLL的方式。在開發的時候遇見這樣的一個問題,例如我在一個EXE中編寫了一個功能非常復雜的函數,在DLL中我想使用到它,如何做呢?其實使用函數的指針就可以很方便的實現。
我們知道DLL的運行空間是和調用它的EXE在一起的。也就是說在這個空間中的資源理論上DLL是都可以使用。所以只要將exe中的函數指針傳給DLL,那么DLL就可以使用這個函數了。
例如在DLL中有函數ModuleSendData作用是讓EXE中傳入函數的指針鏈表,這個鏈表中的函數都是DLL中可能用到的。
SendDataFun: procedure(Casetype: Byte; UserSocket: RUserSocket; Data: array of char; DataLen: Integer);
function ModuleSendData(FunPList: TList): Boolean; stdcall; export;
begin
SendDataFun := FunPList.Items[0];
end;
在EXE中的代碼是:
Linstance:=LoadLibrary(Pchar(Temp));
if Linstance>0 then
begin
//將發送數據的指針傳入DLL插件中
@GiveModuleFun:=GetProcAddress(Linstance,'ModuleSendData');
if @GiveModuleFun<>NIl then
begin
m_FunList:=TList.Create;
//發送數據
t_Pointer:=@DllSendData;
m_FunList.Add(t_Pointer);
GiveModuleFun(m_FunList);
End;
End;
其中DllSendData就是我們想傳入給DLL的函數。
這個時候在DLL中使用SendDataFun就和一般的函數一樣了。
這里注意的一點是Exe中的函數DllSendData我定義的是一個全局函數。原因是這樣取得函數的指針的時候比較簡單(關於類里面的函數指針如何取得我不了解,希望有了解的朋友不吝賜教,感激不盡)。
https://www.cnblogs.com/chenmfly/p/4858926.html