在前面一节,我们了解了如何用C#调用delphi生成的dll,在本节,我们就来用delphi来写一个获取CPU序列号的dll。代码里的注意事项在前一节都有提到,一定要注意。
1、新建delphi工程,工程的动态链接库代码如下:
library PcInfo;
uses
SysUtils,
Classes,
Windows;
{$R *.res}
type
TCPUIDResult = packed record
EAX: DWord;
EBX: DWord;
ECX: DWord;
EDX: DWord;
end;
TCPUInfo =packed record
Name: string[48];
Brand: Word;
APIC: DWORD;
Vendor: string[12];
Frequency: Real;
Family: integer;
Model: integer;
Stepping: integer;
EFamily: integer;
EModel: integer;
EStepping: integer;
MMX: Boolean;
MMXPlus: Boolean;
AMD3DNow: Boolean;
AMD3DNowPlus: Boolean;
SSE: Boolean;
SSE2: Boolean;
IA64: Boolean;
X86_64: Boolean;
ID:string;
end;
//获取cpu序列号
function CPUID(EAX: DWord): TCPUIDResult;
var
rEAX, rEBX, rECX, rEDX: DWord;
begin
asm
push EAX
push EBX
push ECX
push EDX
mov EAX,EAX
db $0F,$A2
mov rEAX,EAX
mov rEBX,EBX
mov rECX,ECX
mov rEDX,EDX
pop EDX
pop ECX
pop EBX
pop EAX
end;
Result.EAX := rEAX;
Result.EBX := rEBX;
Result.ECX := rECX;
Result.EDX := rEDX;
end;
function GetCPUInfo: TCPUInfo;
type
TRegChar = array[0..3] of char;
var
lvCPUID : TCPUIDResult;
I : Integer;
begin
lvCPUID := CPUID(0);
result.ID:=Format('%x-%x-%x-%x',[lvCPUID.EAX,lvCPUID.EBX,lvCPUID.ECX,lvCPUID.EDX]);
Result.Vendor := TRegChar(lvCPUID.EBX) + TRegChar(lvCPUID.EDX) +
TRegChar(lvCPUID.ECX);
lvCPUID := CPUID(1);
result.ID:=result.ID + Format('-%x-%x-%x',[lvCPUID.EAX,lvCPUID.ECX,lvCPUID.EDX]);
Result.Family := (lvCPUID.EAX and $F00) shr 8;
Result.Model := (lvCPUID.EAX and $78) shr 4;
Result.Stepping := (lvCPUID.EAX and $F);
Result.EFamily := (lvCPUID.EAX and $7800000) shr 20;
Result.EModel := (lvCPUID.EAX and $78000) shr 16;
Result.EStepping := (lvCPUID.EAX and $F);
Result.APIC := (lvCPUID.EBX and $1FE00000) shr 23;
Result.Brand := lvCPUID.EBX and $7F;
Result.MMX := (lvCPUID.EDX and $800000) = $800000;
Result.SSE := (lvCPUID.EDX and $2000000) = $2000000;
Result.SSE2 := (lvCPUID.EDX and $4000000) = $4000000;
Result.IA64 := (lvCPUID.EDX and $40000000) = $40000000;
lvCPUID := CPUID($80000001);
Result.MMXPlus := (lvCPUID.EDX and $800000) = $800000;
Result.AMD3DNow := (lvCPUID.EDX and $10000000) = $10000000;
Result.AMD3DNowPlus := (lvCPUID.EDX and $8000000) = $8000000;
Result.X86_64 := (lvCPUID.EDX and $40000000) = $40000000;
if (Result.Vendor = 'GenuineIntel') and ((Result.Family <> 15) or
(Result.EFamily <> 0)) then
Result.Name := Result.Vendor + ' Processor'
else
begin
Result.Name := '';
for i := 2 to 4 do
begin
lvCPUID := CPUID($80000000 + i);
Result.Name := Result.Name +
TRegChar(lvCPUID.EAX) +
TRegChar(lvCPUID.EBX) +
TRegChar(lvCPUID.ECX) +
TRegChar(lvCPUID.EDX);
end;
Result.Name := Trim(Result.Name);
end;
end;
procedure GetCpuNumber(p:PChar);stdcall;
var
cpu: TCpuInfo;
cpuid:PChar;
begin
cpu :=GetCpuInfo;
cpuid:=PChar(cpu.ID); //类型cpu包括了序列号、名称、类型等信息,在这里只返回序列号
StrCopy(p,cpuid);
end;
exports
GetCpuNumber;
begin
end.
2、编译、生成PcInfo.dll,并把dll文件复制到C#项目的bin\debug目录下。
dll下载地址http://download.csdn.net/detail/sunny906/8150053
3、在C#项目里引用PcInfo.dll,代码如下:
// 引用dll
[DllImport("PcInfo.dll")]
public static extern void GetCpuNumber(StringBuilder cpuID);
//调用dll
StringBuilder value = new StringBuilder(256); //注意,value参数对应的是pchar类型的指针变量,所以此处一定要指定参数的大小
GetCpuNumber(value);
Console.WriteLine(value.ToString());
4、为了区分pcinfo返回的CPU序列号和Win32_Processor获取的CPU序列号有何不同,我们也写出调用WMI获取CPU序列号的方法,代码如下:
string cpuID = string.Empty;
ManagementClass mc = new ManagementClass("Win32_Processor");
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject mo in moc)
{
cpuID = mo.Properties["ProcessorId"].Value.ToString();
break;
}
Console.WriteLine(cpuID);
5、运行C#程序,看看这两种方法输出的结果吧,结果是不是很不一样呢,个人更偏向于调用汇编所取得的值。