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

XE5&D7 相同代碼不同結果

缺席
heart75047
一般會員


發表:9
回覆:13
積分:19
註冊:2010-05-20

發送簡訊給我
#1 引用回覆 回覆 發表時間:2014-03-27 10:09:11 IP:59.126.xxx.xxx 訂閱
以下是抓取網卡的代碼

[code delphi]
unit MACUnit;
interface
uses windows,SysUtils,dialogs;
const
MAX_HOSTNAME_LEN = 128; { from IPTYPES.H }
MAX_DOMAIN_NAME_LEN = 128;
MAX_SCOPE_ID_LEN = 256;
MAX_ADAPTER_NAME_LENGTH = 256;
MAX_ADAPTER_DESCRIPTION_LENGTH = 128;
MAX_ADAPTER_ADDRESS_LENGTH = 8;

type
TIPAddressString = array[0..4 * 4 - 1] of Char;
PIPAddrString = ^TIPAddrString;
TIPAddrString = record
Next: PIPAddrString;
IPAddress: TIPAddressString;
IPMask: TIPAddressString;
Context: Integer;
end;
PFixedInfo = ^TFixedInfo;
TFixedInfo = record { FIXED_INFO }
HostName: array[0..MAX_HOSTNAME_LEN 3] of Char;
DomainName: array[0..MAX_DOMAIN_NAME_LEN 3] of Char;
CurrentDNSServer: PIPAddrString;
DNSServerList: TIPAddrString;
NodeType: Integer;
ScopeId: array[0..MAX_SCOPE_ID_LEN 3] of Char;
EnableRouting: Integer;
EnableProxy: Integer;
EnableDNS: Integer;
end;
PIPAdapterInfo = ^TIPAdapterInfo;
TIPAdapterInfo = record { IP_ADAPTER_INFO }
Next: PIPAdapterInfo;
ComboIndex: Integer;
AdapterName: array[0..MAX_ADAPTER_NAME_LENGTH 3] of Char;
Description: array[0..MAX_ADAPTER_DESCRIPTION_LENGTH 3] of Char;
AddressLength: Integer;
Address: array[1..MAX_ADAPTER_ADDRESS_LENGTH] of Byte;
Index: Integer;
_Type: Integer;
DHCPEnabled: Integer;
CurrentIPAddress: PIPAddrString;
IPAddressList: TIPAddrString;
GatewayList: TIPAddrString;
DHCPServer: TIPAddrString;
HaveWINS: Bool;
PrimaryWINSServer: TIPAddrString;
SecondaryWINSServer: TIPAddrString;
LeaseObtained: Integer;
LeaseExpires: Integer;
end;

FUNCTION GetAdapterInformation:string;
implementation
function GetAdaptersInfo(AI: PIPAdapterInfo; var BufLen: Integer): Integer;
stdcall; external 'iphlpapi.dll' Name 'GetAdaptersInfo';

FUNCTION GetAdapterInformation:string; stdcall;
var
AI, Work: PIPAdapterInfo;
Size: Integer;
Res: Integer;
I: Integer;
function MACToStr(ByteArr: PByte; Len: Integer): string;
begin
Result := '';
while (Len > 0) do begin
Result := Result IntToHex(ByteArr^, 2) '-';
ByteArr := Pointer(Integer(ByteArr) SizeOf(Byte));
Dec(Len);
end;
SetLength(Result, Length(Result) - 1); { remove last dash }
end;
function GetAddrString(Addr: PIPAddrString): string;
begin
Result := '';
while (Addr <> nil) do begin
Result := Result 'A: ' Addr^.IPAddress ' M: ' Addr^.IPMask #13;
Addr := Addr^.Next;
end;
end;
function TimeTToDateTimeStr(TimeT: Integer): string;
const UnixDateDelta = 25569; { days between 12/31/1899 and 1/1/1970 }
var
DT: TDateTime;
TZ: TTimeZoneInformation;
Res: DWord;
begin
if (TimeT = 0) then Result := ''
else begin
{ Unix TIME_T is secs since 1/1/1970 }
DT := UnixDateDelta (TimeT / (24 * 60 * 60)); { in UTC }
{ calculate bias }
Res := GetTimeZoneInformation(TZ);
if (Res = TIME_ZONE_ID_INVALID) then RaiseLastWin32Error;
if (Res = TIME_ZONE_ID_STANDARD) then begin
DT := DT - ((TZ.Bias TZ.StandardBias) / (24 * 60));
Result := DateTimeToStr(DT) ' ' WideCharToString(TZ.StandardName);
end
else begin { daylight saving time }
DT := DT - ((TZ.Bias TZ.DaylightBias) / (24 * 60));
Result := DateTimeToStr(DT) ' ' WideCharToString(TZ.DaylightName);
end;
end;
end;
begin
Size := 5120;
GetMem(AI, Size);
Res := GetAdaptersInfo(AI, Size);
if (Res <> ERROR_SUCCESS) then begin
SetLastError(Res);
RaiseLastWin32Error;
end;
Work := AI;
repeat
//Add(' Adapter address: ' MACToStr(@Work^.Address, Work^.AddressLength));
//showmessage(' Adapter address: ' MACToStr(@Work^.Address, Work^.AddressLength));
//showmessage(MACToStr(@Work^.Address, Work^.AddressLength));
result:=MACToStr(@Work^.Address, Work^.AddressLength);
Work := Work^.Next;
until (Work = nil);
FreeMem(AI);
end;

end.

[/code]

使用Delphi7 可以正確抓到 MAC Address

使用XE5 抓到的是空白

將Delphi7的 system.pas直接貼上XE5裡面 還是空白

於是我就想 如果用Delphi7 寫成DLL 再讓XE5呼叫 應該就能抓到正確的MAC Address

以下是Delphi7 的DLL代碼

[code delphi]
library mygetmac;
{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
uses
SysUtils,
Classes,
windows,
dialogs;

const
MAX_HOSTNAME_LEN = 128; { from IPTYPES.H }
MAX_DOMAIN_NAME_LEN = 128;
MAX_SCOPE_ID_LEN = 256;
MAX_ADAPTER_NAME_LENGTH = 256;
MAX_ADAPTER_DESCRIPTION_LENGTH = 128;
MAX_ADAPTER_ADDRESS_LENGTH = 8;

type
TIPAddressString = array[0..4 * 4 - 1] of Char;
PIPAddrString = ^TIPAddrString;
TIPAddrString = record
Next: PIPAddrString;
IPAddress: TIPAddressString;
IPMask: TIPAddressString;
Context: Integer;
end;
PFixedInfo = ^TFixedInfo;
TFixedInfo = record { FIXED_INFO }
HostName: array[0..MAX_HOSTNAME_LEN 3] of Char;
DomainName: array[0..MAX_DOMAIN_NAME_LEN 3] of Char;
CurrentDNSServer: PIPAddrString;
DNSServerList: TIPAddrString;
NodeType: Integer;
ScopeId: array[0..MAX_SCOPE_ID_LEN 3] of Char;
EnableRouting: Integer;
EnableProxy: Integer;
EnableDNS: Integer;
end;
PIPAdapterInfo = ^TIPAdapterInfo;
TIPAdapterInfo = record { IP_ADAPTER_INFO }
Next: PIPAdapterInfo;
ComboIndex: Integer;
AdapterName: array[0..MAX_ADAPTER_NAME_LENGTH 3] of Char;
Description: array[0..MAX_ADAPTER_DESCRIPTION_LENGTH 3] of Char;
AddressLength: Integer;
Address: array[1..MAX_ADAPTER_ADDRESS_LENGTH] of Byte;
Index: Integer;
_Type: Integer;
DHCPEnabled: Integer;
CurrentIPAddress: PIPAddrString;
IPAddressList: TIPAddrString;
GatewayList: TIPAddrString;
DHCPServer: TIPAddrString;
HaveWINS: Bool;
PrimaryWINSServer: TIPAddrString;
SecondaryWINSServer: TIPAddrString;
LeaseObtained: Integer;
LeaseExpires: Integer;
end;

//FUNCTION GetAdapterInformation:string;
function GetAdaptersInfo(AI: PIPAdapterInfo; var BufLen: Integer): Integer;
stdcall; external 'iphlpapi.dll' Name 'GetAdaptersInfo';

{$R *.res}
//FUNCTION GetAdapterInformation:string;
FUNCTION GetAdapterInformation:pchar; stdcall;
var
AI, Work: PIPAdapterInfo;
Size: Integer;
Res: Integer;
I: Integer;
function MACToStr(ByteArr: PByte; Len: Integer): string;
begin
Result := '';
while (Len > 0) do begin
Result := Result IntToHex(ByteArr^, 2) '-';
ByteArr := Pointer(Integer(ByteArr) SizeOf(Byte));
Dec(Len);
end;
SetLength(Result, Length(Result) - 1); { remove last dash }
end;
function GetAddrString(Addr: PIPAddrString): string;
begin
Result := '';
while (Addr <> nil) do begin
Result := Result 'A: ' Addr^.IPAddress ' M: ' Addr^.IPMask #13;
Addr := Addr^.Next;
end;
end;
function TimeTToDateTimeStr(TimeT: Integer): string;
const UnixDateDelta = 25569; { days between 12/31/1899 and 1/1/1970 }
var
DT: TDateTime;
TZ: TTimeZoneInformation;
Res: DWord;
begin
if (TimeT = 0) then Result := ''
else begin
{ Unix TIME_T is secs since 1/1/1970 }
DT := UnixDateDelta (TimeT / (24 * 60 * 60)); { in UTC }
{ calculate bias }
Res := GetTimeZoneInformation(TZ);
if (Res = TIME_ZONE_ID_INVALID) then RaiseLastWin32Error;
if (Res = TIME_ZONE_ID_STANDARD) then begin
DT := DT - ((TZ.Bias TZ.StandardBias) / (24 * 60));
Result := DateTimeToStr(DT) ' ' WideCharToString(TZ.StandardName);
end
else begin { daylight saving time }
DT := DT - ((TZ.Bias TZ.DaylightBias) / (24 * 60));
Result := DateTimeToStr(DT) ' ' WideCharToString(TZ.DaylightName);
end;
end;
end;
begin
Size := 5120;
GetMem(AI, Size);
Res := GetAdaptersInfo(AI, Size);
if (Res <> ERROR_SUCCESS) then begin
SetLastError(Res);
RaiseLastWin32Error;
end;
Work := AI;
repeat
//Add(' Adapter address: ' MACToStr(@Work^.Address, Work^.AddressLength));
//showmessage(' Adapter address: ' MACToStr(@Work^.Address, Work^.AddressLength));
//showmessage(MACToStr(@Work^.Address, Work^.AddressLength));
result:=PChar(MACToStr(@Work^.Address, Work^.AddressLength));
Work := Work^.Next;
until (Work = nil);
FreeMem(AI);
end;

exports
GetAdapterInformation name 'GetAdapterInformation';

begin
end.

[/code]

基本上都差不多 只是String 換成Pchar

Compile也過了

可是連用delphi7呼叫還是空白

還是不能在dll裡面呼叫另一個dll??

執行程式環境是 win7 64 旗艦版

求解
附加檔案:533388475bd22_mac.rar
編輯記錄
heart75047 重新編輯於 2014-03-27 10:26:16, 註解 無‧
heart75047 重新編輯於 2014-03-27 10:53:52, 註解 無‧
heart75047 重新編輯於 2014-03-27 11:00:49, 註解 無‧
heart75047 重新編輯於 2014-03-27 11:07:47, 註解 無‧
heart75047 重新編輯於 2014-03-27 11:18:56, 註解 無‧
P.D.
版主


發表:571
回覆:3880
積分:3666
註冊:2006-10-31

發送簡訊給我
#2 引用回覆 回覆 發表時間:2014-04-21 09:47:24 IP:118.169.xxx.xxx 未訂閱
這部份應該XE5討論非常多了, 是在型別STRING版本的不同, 不過我也不會解, 我也有一支類似抓MAC的, 在早期DELPHI版本OK, 換上XE5也是不行, 所以我的解法與你類似, 
但我不用DLL(擔心有不相容的執行), 所以我是用EXE執行, 利用 XE5去CALL Dx的EXE, 把 Dx的結果存到一個檔案或資料庫, 再由 XE5 去讀取,
看來也只能這樣做了, 要不然就要再GOOGLE 有沒有XE5 的 MAC ADDRESS
系統時間:2017-10-19 19:03:10
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!