全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1333
推到 Plurk!
推到 Facebook!

相同程式碼為什麼在PC可執行在NB卻不能?

答題得分者是:aftcast
ry_lee
高階會員


發表:367
回覆:251
積分:123
註冊:2002-03-19

發送簡訊給我
#1 引用回覆 回覆 發表時間:2010-11-12 00:33:58 IP:111.253.xxx.xxx 未訂閱
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
const
MAX_ADAPTER_NAME_LENGTH = 256;
MAX_ADAPTER_DEforbiddenION_LENGTH = 128;
MAX_ADAPTER_ADDRESS_LENGTH = 8;
type
//------IP address structures---------------------------------------------------
PIP_ADDRESS_STRING = ^IP_ADDRESS_STRING;
IP_ADDRESS_STRING = array[0..15] of char; // IP as string
PIP_ADDR_STRING = ^IP_ADDR_STRING;
IP_ADDR_STRING = record
Next: PIP_ADDR_STRING;
IpAddress: IP_ADDRESS_STRING;
IpMask: IP_ADDRESS_STRING;
Context: DWORD;
end;
//------ADAPTER INFO STRUCTURES-------------------------------------------------
PIP_ADAPTER_INFO = ^IP_ADAPTER_INFO;
IP_ADAPTER_INFO = record
Next: PIP_ADAPTER_INFO;
ComboIndex: DWORD;
AdapterName: array[1..MAX_ADAPTER_NAME_LENGTH 4] of char;
Deforbiddenion: array[1..MAX_ADAPTER_DEforbiddenION_LENGTH 4] of char;
AddressLength: UINT;
Address: array[1..MAX_ADAPTER_ADDRESS_LENGTH] of byte;
Index: DWORD;
aType: UINT;
DHCPEnabled: UINT;
CurrentIPAddress: PIP_ADDR_STRING;
IPAddressList: IP_ADDR_STRING;
GatewayList: IP_ADDR_STRING;
DHCPServer: IP_ADDR_STRING;
HaveWINS: BOOL;
PrimaryWINSServer: IP_ADDR_STRING;
SecondaryWINSServer: IP_ADDR_STRING;
LeaseObtained: LongInt;
LeaseExpires: LongInt;
//SpareStuff: array [1..200] of char;
end;
function GetAdaptersInfo(pAdapterInfo: PIP_ADAPTER_INFO;
pOutBufLen: PULONG): DWORD; stdcall;
external 'Iphlpapi.dll' name 'GetAdaptersInfo';
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
const
AddrLen = 6;
var
AdapterInfo: IP_ADAPTER_INFO;
ret: DWORD;
i: integer;
Next: PIP_ADAPTER_INFO;
sMAC: string;
OutBufLen: ULONG;
//
errormessage:pointer;
errorcode:dword;
begin
memo1.Clear;
OutBufLen := SizeOf(IP_ADAPTER_INFO);
ret:= GetAdaptersInfo(@AdapterInfo, @OutBufLen);
if ret = 0 then
begin
Next:= @AdapterInfo;
repeat
if next <> nil then
begin
Memo1.Lines.Add('Deforbiddenion: ' Next^.Deforbiddenion);
sMAC :='MAC address: ';
for i := 1 to AddrLen do //為何由i:=0改為i:=1 to AddrLen do 因為 Next^.Address[i] 及 Address: array[1..MAX_ADAPTER_ADDRESS_LENGTH] of byte;
begin
sMAC := sMAC IntToHex(Next^.Address[i], 2);
{if i <> AddrLen then
sMAC := sMAC '-'; }
end;
Memo1.Lines.Add(sMAC);
end;
Next:= AdapterInfo.Next;
until Next = nil;
end
else
begin
if ret = ERROR_BUFFER_OVERFLOW then
showmessage('ERROR_BUFFER_OVERFLOW ,errorcode = ' inttostr(ret))
else
showmessage('errorcode = ' inttostr(ret)); //=>ERROR_BUFFER_OVERFLOW 即 111
end;
end;

end.
1.在PC可取出正確之MAC,但在NB卻得到ERROR_BUFFER_OVERFLOW之錯誤訊息,請問是不是我的NB有兩個MAC之故呢?我在NB之DOS視窗執行 IPCONFIG /ALL,會列出兩個MAC,一個好像是無線網卡,一個是乙太網卡,但在PC執行IPCONFIG /ALL,只列出一個網卡MAC ?

2.還是程式碼錯誤之問題呢?

編輯記錄
ry_lee 重新編輯於 2010-11-11 09:38:55, 註解 無‧
aftcast
站務副站長


發表:81
回覆:1482
積分:1762
註冊:2002-11-21

發送簡訊給我
#2 引用回覆 回覆 發表時間:2010-11-12 14:47:03 IP:210.64.xxx.xxx 訂閱
我用c++的語法重點和你說…

ret:= GetAdaptersInfo(@AdapterInfo, @OutBufLen);

上面那行要改。因為Adapterinfo只有一個結構體,但這裡其實應該要放一個 "指標" 指向一個 「足夠存放下1至數個AdapterInfo結構的linked list 空間」,所以你單純的僅指向 1 個Adapterinfo 的空間,這樣可能會造成多網卡的資料不足以存入該配置空間!

我拿msdn上的範例讓你參考,但要自己去改一下成delphi的記憶體配置:


[code cpp]
PIP_ADAPTER_INFO pAdapterInfo;
PIP_ADAPTER_INFO pAdapter = NULL;
DWORD dwRetVal = 0;

pAdapterInfo = (IP_ADAPTER_INFO *) malloc( sizeof(IP_ADAPTER_INFO) );
ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);

// Make an initial call to GetAdaptersInfo to get
// the necessary size into the ulOutBufLen variable
if (GetAdaptersInfo( pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
free(pAdapterInfo);
pAdapterInfo = (IP_ADAPTER_INFO *) malloc (ulOutBufLen); // 注意這裡 1
}

if ((dwRetVal = GetAdaptersInfo( pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
// 注意2
[/code]

大概上是這樣改
PAdapterInfo: PIP_ADAPTER_INFO;
if GetAdaptersInfo(@AdapterInfo, @OutBufLen) = ERROR_BUFFER_OVERFLOW
PAdapterInfo := AllocMem(OutBufLen);
然後再配記憶體,參考上面的「注意1」
然後才是真的再取一次 「注意2」,然後再接你原來的delphi code…
GetAdaptersInfo(PAdapterInfo, @OutBufLen);



------



蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
編輯記錄
aftcast 重新編輯於 2010-11-11 23:48:37, 註解 無‧
aftcast 重新編輯於 2010-11-11 23:56:20, 註解 無‧
系統時間:2017-10-20 17:07:20
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!