为什么我用静态调用 DLL 里面的函数就没有问题, 如改用动态调用就出现如下问题
(存取地址00403E46违例发生在模块 'Project1.exe'中, 读在地址00D71E68里.)
源码如下:主程序文件:
type
TLanCardID = function:string;stdcall;
TGetNetBIOSAddress = function:string;stdcall;procedure TForm1.Button1Click(Sender: TObject);
var
proc:TLanCardID;
aptr:TFarproc;
Moudle:THandle;
s:string;
begin
Moudle:= Loadlibrary('IntDLL.dll');
if Moudle <> 0 then
try
begin
aptr:= GetProcAddress(Moudle,'GetIP');
if aptr <> nil then
begin
proc:=TLanCardID(aptr);
s := proc;
Edit1.Text:= '本机IP地址: '+ s;
end;
end;
finally
Freelibrary(Moudle);
end;
end;procedure TForm1.Button5Click(Sender: TObject);
var
proc1:TGetNetBIOSAddress;
aptr1:TFarproc;
Moudle1:Integer;
s1:string;
begin
Moudle1:= Loadlibrary('IntDLL.dll');
if Moudle1 <> 0 then
try
begin
aptr1:= GetProcAddress(Moudle1,'GetNetBIOSAddress');
if aptr1 <> nil then
begin
proc1:=TGetNetBIOSAddress(aptr1);
s1 := proc1;
Edit3.Text:= 'NetBios地址: '+ s1;
end;
end;
finally
Freelibrary(Moudle1);
end;
end;
DLL文件:
library IntDLL;uses
SysUtils,
Classes,
netfun in 'netfun.pas';{$R *.res}exports
GetNetBIOSAddress,
GetIP;begin
end.////////////////////////////////////
netfun文件:
unit netfun;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics,Controls,
Forms, Dialogs, wininet, Winsock, NB30, Registry, ActiveX;function GetNetBIOSAddress : string;stdcall;function GetIP:string;stdcall;implementationfunction GetNetBIOSAddress : string;stdcall;
var
ncb : TNCB;
status : TAdapterStatus;
lanenum : TLanaEnum; procedure ResetAdapter (num : char);
begin
fillchar(ncb,sizeof(ncb),0);
ncb.ncb_command:=char(NCBRESET);
ncb.ncb_lana_num:=num;
Netbios(@ncb);
end;var
lanNum : char;
address : record
part1 : Longint;
part2 : Word;//Smallint;
end absolute status;
begin
Result:=''; fillchar(ncb,sizeof(ncb),0);
ncb.ncb_command:=char(NCBENUM);
ncb.ncb_buffer:=@lanenum;
ncb.ncb_length:=sizeof(lanenum);
Netbios(@ncb); if lanenum.length=#0 then exit;
lanNum:=lanenum.lana[0]; ResetAdapter(lanNum); fillchar(ncb,sizeof(ncb),0);
ncb.ncb_command:=char(NCBASTAT);
ncb.ncb_lana_num:=lanNum;
ncb.ncb_callname[0]:='*';
ncb.ncb_buffer:=@status;
ncb.ncb_length:=sizeof(status);
Netbios(@ncb);
ResetAdapter(lanNum); Result:=Format('%x%x',[address.part1,address.part2]);
end;function GetIP:string;stdcall;
var
WSAData:TWSAData;
HostName:array[0..MAX_COMPUTERNAME_LENGTH] of Char;
HostEnt:PHostEnt;
LastIP:PInAddr;
IPList:^PInAddr;
begin
result:='';
if 0=WSAStartup(MAKEWORD(1,1), WSAData) then
try
if 0=gethostname(HostName, MAX_COMPUTERNAME_LENGTH+1) then
begin
HostEnt:=gethostbyname(HostName);
if HostEnt<>nil then
begin
IPList:=Pointer(HostEnt^.h_addr_list);
repeat
LastIP:=IPList^;
INC(IPList);
until
IPList^=nil;
if LastIP<>nil then
result:=inet_ntoa(LastIP^);
end;
end;
finally
WSACleanup;
end;
end;end.
(存取地址00403E46违例发生在模块 'Project1.exe'中, 读在地址00D71E68里.)
源码如下:主程序文件:
type
TLanCardID = function:string;stdcall;
TGetNetBIOSAddress = function:string;stdcall;procedure TForm1.Button1Click(Sender: TObject);
var
proc:TLanCardID;
aptr:TFarproc;
Moudle:THandle;
s:string;
begin
Moudle:= Loadlibrary('IntDLL.dll');
if Moudle <> 0 then
try
begin
aptr:= GetProcAddress(Moudle,'GetIP');
if aptr <> nil then
begin
proc:=TLanCardID(aptr);
s := proc;
Edit1.Text:= '本机IP地址: '+ s;
end;
end;
finally
Freelibrary(Moudle);
end;
end;procedure TForm1.Button5Click(Sender: TObject);
var
proc1:TGetNetBIOSAddress;
aptr1:TFarproc;
Moudle1:Integer;
s1:string;
begin
Moudle1:= Loadlibrary('IntDLL.dll');
if Moudle1 <> 0 then
try
begin
aptr1:= GetProcAddress(Moudle1,'GetNetBIOSAddress');
if aptr1 <> nil then
begin
proc1:=TGetNetBIOSAddress(aptr1);
s1 := proc1;
Edit3.Text:= 'NetBios地址: '+ s1;
end;
end;
finally
Freelibrary(Moudle1);
end;
end;
DLL文件:
library IntDLL;uses
SysUtils,
Classes,
netfun in 'netfun.pas';{$R *.res}exports
GetNetBIOSAddress,
GetIP;begin
end.////////////////////////////////////
netfun文件:
unit netfun;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics,Controls,
Forms, Dialogs, wininet, Winsock, NB30, Registry, ActiveX;function GetNetBIOSAddress : string;stdcall;function GetIP:string;stdcall;implementationfunction GetNetBIOSAddress : string;stdcall;
var
ncb : TNCB;
status : TAdapterStatus;
lanenum : TLanaEnum; procedure ResetAdapter (num : char);
begin
fillchar(ncb,sizeof(ncb),0);
ncb.ncb_command:=char(NCBRESET);
ncb.ncb_lana_num:=num;
Netbios(@ncb);
end;var
lanNum : char;
address : record
part1 : Longint;
part2 : Word;//Smallint;
end absolute status;
begin
Result:=''; fillchar(ncb,sizeof(ncb),0);
ncb.ncb_command:=char(NCBENUM);
ncb.ncb_buffer:=@lanenum;
ncb.ncb_length:=sizeof(lanenum);
Netbios(@ncb); if lanenum.length=#0 then exit;
lanNum:=lanenum.lana[0]; ResetAdapter(lanNum); fillchar(ncb,sizeof(ncb),0);
ncb.ncb_command:=char(NCBASTAT);
ncb.ncb_lana_num:=lanNum;
ncb.ncb_callname[0]:='*';
ncb.ncb_buffer:=@status;
ncb.ncb_length:=sizeof(status);
Netbios(@ncb);
ResetAdapter(lanNum); Result:=Format('%x%x',[address.part1,address.part2]);
end;function GetIP:string;stdcall;
var
WSAData:TWSAData;
HostName:array[0..MAX_COMPUTERNAME_LENGTH] of Char;
HostEnt:PHostEnt;
LastIP:PInAddr;
IPList:^PInAddr;
begin
result:='';
if 0=WSAStartup(MAKEWORD(1,1), WSAData) then
try
if 0=gethostname(HostName, MAX_COMPUTERNAME_LENGTH+1) then
begin
HostEnt:=gethostbyname(HostName);
if HostEnt<>nil then
begin
IPList:=Pointer(HostEnt^.h_addr_list);
repeat
LastIP:=IPList^;
INC(IPList);
until
IPList^=nil;
if LastIP<>nil then
result:=inet_ntoa(LastIP^);
end;
end;
finally
WSACleanup;
end;
end;end.
解决方案 »
- VFP表格的问题。郁闷!!!
- 有关EXE文件耗资源的问题
- BDE连接Access数据库需要什么Dll文件支持,求助???在线等~~
- 控制word,做字符替换出现承载体接收到坏的数据
- 大家来讨论,做一名程序员最重要的条件是什么?
- 请教:怎样备份SQL SERVER中数据库的表?
- teechart一个问题,折腾了很久,哪位可否随手帮我解决掉他,谢谢
- delphi菜鸟?想实现下面这种功能??????????
- 求一份delphi hook D3D使游戏黑屏的代码
- 快来拿分呀!快来拿分呀!快来拿分呀!快来拿分呀!快来拿分呀!
- 如果对A、C、B、5、8、H、5、U进行全排列,数字和字母不能重复,并打印出来,算法如何写[事成后给200分]
- 大菜鸟的小问题---如何在窗体上显示文字,不用label
var
guid: TGUID;
i: integer;
begin
result := '';
CoCreateGUID(guid);
for i := Low(guid.D4)+2 to High(guid.D4) do
begin
result := result + IntTohex(guid.D4[i],2);
end;
end;
result := PChar(result);
可以啊
函数返回值也改为PChar........