静态调用DLL改成动态调用DLL出错的问题 ( 积分: 200 )

  • 主题发起人 主题发起人 jianguobu
  • 开始时间 开始时间
J

jianguobu

Unregistered / Unconfirmed
GUEST, unregistred user!
描述:网络服务函数,存在于NetApi32.dll文件中;通过NetServerEnum函数可取得装有SQL Server服务端的计算机列表,只装有SQL Server客户端的计算机将不会被列举其中;如果一台计算机的SQL Server服务刚刚启动,那么此函数将会过很久才能取到该计算机。

列表类型:仅列举装有“服务端”的计算机。

适用条件:有NetApi32.dll文件。

速度:快

调用示例:GetSQLServerList(ListBox1.items);

代码:

type
NET_API_STATUS = DWORD;
PServerInfo100 = ^TServerInfo100;
_SERVER_INFO_100 = record
sv100_platform_id: DWORD;
sv100_name: LPWSTR;
end;

{$EXTERNALSYM _SERVER_INFO_100}
TServerInfo100 = _SERVER_INFO_100;
SERVER_INFO_100 = _SERVER_INFO_100;
{$EXTERNALSYM SERVER_INFO_100}
const
NERR_Success = 0;
MAX_PREFERRED_LENGTH = DWORD(-1);
SV_TYPE_SQLSERVER = $00000004;

function NetApiBufferAllocate(ByteCount: DWORD; var Buffer: Pointer):

NET_API_STATUS; stdcall; external 'netapi32.dll' name 'NetApiBufferAllocate';



function NetServerEnum(ServerName: LPCWSTR; Level: DWORD; var BufPtr: Pointer;

PrefMaxLen: DWORD; var EntriesRead: DWORD; var TotalEntries: DWORD;

ServerType: DWORD; Domain: LPCWSTR; ResumeHandle: PDWORD): NET_API_STATUS;

stdcall; external 'netapi32.dll' name 'NetServerEnum';



function NetApiBufferFree(Buffer: Pointer): NET_API_STATUS; stdcall; external

'netapi32.dll' name 'NetApiBufferFree';



function GetSQLServerList(var AList: TStrings; pwcServerName: PWChar = nil;

pwcDomain: PWChar = nil): Boolean;

var

NetAPIStatus: DWORD;

dwLevel: DWORD;

pReturnSvrInfo: Pointer;

dwPrefMaxLen: DWORD;

dwEntriesRead: DWORD;

dwTotalEntries: DWORD;

dwServerType: DWORD;

dwResumeHandle: PDWORD;

pCurSvrInfo: PServerInfo100;

i, j: Integer;

begin

Result := True;

try

dwLevel := 100;

pReturnSvrInfo := nil;

dwPrefMaxLen := MAX_PREFERRED_LENGTH;

dwEntriesRead := 0;

dwTotalEntries := 0;

dwServerType := SV_TYPE_SQLSERVER; //服务器类型

dwResumeHandle := nil;



NetApiBufferAllocate(SizeOf(pReturnSvrInfo), pReturnSvrInfo);

try

NetAPIStatus := NetServerEnum(pwcServerName, dwLevel, pReturnSvrInfo,

dwPrefMaxLen, dwEntriesRead, dwTotalEntries, dwServerType, pwcDomain,

dwResumeHandle);



if ((NetAPIStatus = NERR_Success) or (NetAPIStatus = ERROR_MORE_DATA)) and

(pReturnSvrInfo <> nil) then

begin

pCurSvrInfo := pReturnSvrInfo;



// 循环取得所有SQL Server服务器

i := 0;

j := dwEntriesRead;

while i < j do

begin

if pCurSvrInfo = nil then

Break;



with AList do

Add(pCurSvrInfo^.sv100_name);



Inc(i);

Inc(pCurSvrInfo);

end;

end;

finally

if Assigned(pReturnSvrInfo) then

NetApiBufferFree(pReturnSvrInfo);

end;

except

Result := False;

end;

end;

改成动态的如下:
type
NET_API_STATUS = DWORD;
PServerInfo100 = ^TServerInfo100;
_SERVER_INFO_100 = record
sv100_platform_id: DWORD;
sv100_name: LPWSTR;
end;

{$EXTERNALSYM _SERVER_INFO_100}
TServerInfo100 = _SERVER_INFO_100;
SERVER_INFO_100 = _SERVER_INFO_100;
{$EXTERNALSYM SERVER_INFO_100}

TNetApiBufferAllocate = function(ByteCount: DWORD; var Buffer: Pointer): NET_API_STATUS;
TNetServerEnum= function(ServerName: LPCWSTR; Level: DWORD; var BufPtr: Pointer;
PrefMaxLen: DWORD; var EntriesRead: DWORD; var TotalEntries: DWORD;
ServerType: DWORD; Domain: LPCWSTR; ResumeHandle: PDWORD): NET_API_STATUS;
TNetApiBufferFree= function(Buffer: Pointer): NET_API_STATUS;

const
NERR_Success = 0;
MAX_PREFERRED_LENGTH = DWORD(-1);
SV_TYPE_SQLSERVER = $00000004;
function GetSQLServerList(AList: TStrings; pwcServerName: PWChar = nil;pwcDomain: PWChar = nil): Boolean;
var
NetAPIStatus: DWORD;
dwLevel: DWORD;
pReturnSvrInfo: Pointer;
dwPrefMaxLen: DWORD;
dwEntriesRead: DWORD;
dwTotalEntries: DWORD;
dwServerType: DWORD;
dwResumeHandle: PDWORD;
pCurSvrInfo: PServerInfo100;
i, j: Integer;
NetApiBufferAllocate : TNetApiBufferAllocate;
NetServerEnum : TNetServerEnum;
NetApiBufferFree : TNetApiBufferFree;
LibHandle:THandle;
begin
Result := True;
try
dwLevel := 100;
pReturnSvrInfo := nil;
dwPrefMaxLen := MAX_PREFERRED_LENGTH;
dwEntriesRead := 0;
dwTotalEntries := 0;
dwServerType := SV_TYPE_SQLSERVER; //服务器类型
dwResumeHandle := nil;
try
LibHandle := LoadLibrary(pchar('netapi32.dll'));
if LibHandle <> 0 then begin
NetApiBufferAllocate := GetProcAddress(LibHandle, 'NetApiBufferAllocate');
if @NetApiBufferAllocate <> nil then
NetApiBufferAllocate(SizeOf(pReturnSvrInfo), pReturnSvrInfo) //执行到此处出错,请大家帮忙看看是什么原因
else try
NetServerEnum := GetProcAddress(LibHandle, 'NetServerEnum');
if @NetServerEnum <> nil then begin
NetAPIStatus := NetServerEnum(pwcServerName, dwLevel, pReturnSvrInfo,
dwPrefMaxLen, dwEntriesRead, dwTotalEntries, dwServerType, pwcDomain,
dwResumeHandle);
if ((NetAPIStatus = NERR_Success) or (NetAPIStatus = ERROR_MORE_DATA)) and
(pReturnSvrInfo <> nil) then
begin
pCurSvrInfo := pReturnSvrInfo;
// 循环取得所有SQL Server服务器
i := 0;
j := dwEntriesRead;
while i < j do
begin
if pCurSvrInfo = nil then
Break;
with AList do
Add(pCurSvrInfo^.sv100_name);
Inc(i);
Inc(pCurSvrInfo);
end;
end;
end;
finally
if Assigned(pReturnSvrInfo) then begin
NetApiBufferFree := GetProcAddress(LibHandle, 'NetApiBufferFree');
if @NetApiBufferFree <> nil then
NetApiBufferFree(pReturnSvrInfo);
end;
FreeLibrary(LibHandle);
end;
end;
Finally
FreeLibrary(LibHandle);
end;
except
Result := False;
end;
end;
 
描述:网络服务函数,存在于NetApi32.dll文件中;通过NetServerEnum函数可取得装有SQL Server服务端的计算机列表,只装有SQL Server客户端的计算机将不会被列举其中;如果一台计算机的SQL Server服务刚刚启动,那么此函数将会过很久才能取到该计算机。

列表类型:仅列举装有“服务端”的计算机。

适用条件:有NetApi32.dll文件。

速度:快

调用示例:GetSQLServerList(ListBox1.items);

代码:

type
NET_API_STATUS = DWORD;
PServerInfo100 = ^TServerInfo100;
_SERVER_INFO_100 = record
sv100_platform_id: DWORD;
sv100_name: LPWSTR;
end;

{$EXTERNALSYM _SERVER_INFO_100}
TServerInfo100 = _SERVER_INFO_100;
SERVER_INFO_100 = _SERVER_INFO_100;
{$EXTERNALSYM SERVER_INFO_100}
const
NERR_Success = 0;
MAX_PREFERRED_LENGTH = DWORD(-1);
SV_TYPE_SQLSERVER = $00000004;

function NetApiBufferAllocate(ByteCount: DWORD; var Buffer: Pointer):

NET_API_STATUS; stdcall; external 'netapi32.dll' name 'NetApiBufferAllocate';



function NetServerEnum(ServerName: LPCWSTR; Level: DWORD; var BufPtr: Pointer;

PrefMaxLen: DWORD; var EntriesRead: DWORD; var TotalEntries: DWORD;

ServerType: DWORD; Domain: LPCWSTR; ResumeHandle: PDWORD): NET_API_STATUS;

stdcall; external 'netapi32.dll' name 'NetServerEnum';



function NetApiBufferFree(Buffer: Pointer): NET_API_STATUS; stdcall; external

'netapi32.dll' name 'NetApiBufferFree';



function GetSQLServerList(var AList: TStrings; pwcServerName: PWChar = nil;

pwcDomain: PWChar = nil): Boolean;

var

NetAPIStatus: DWORD;

dwLevel: DWORD;

pReturnSvrInfo: Pointer;

dwPrefMaxLen: DWORD;

dwEntriesRead: DWORD;

dwTotalEntries: DWORD;

dwServerType: DWORD;

dwResumeHandle: PDWORD;

pCurSvrInfo: PServerInfo100;

i, j: Integer;

begin

Result := True;

try

dwLevel := 100;

pReturnSvrInfo := nil;

dwPrefMaxLen := MAX_PREFERRED_LENGTH;

dwEntriesRead := 0;

dwTotalEntries := 0;

dwServerType := SV_TYPE_SQLSERVER; //服务器类型

dwResumeHandle := nil;



NetApiBufferAllocate(SizeOf(pReturnSvrInfo), pReturnSvrInfo);

try

NetAPIStatus := NetServerEnum(pwcServerName, dwLevel, pReturnSvrInfo,

dwPrefMaxLen, dwEntriesRead, dwTotalEntries, dwServerType, pwcDomain,

dwResumeHandle);



if ((NetAPIStatus = NERR_Success) or (NetAPIStatus = ERROR_MORE_DATA)) and

(pReturnSvrInfo <> nil) then

begin

pCurSvrInfo := pReturnSvrInfo;



// 循环取得所有SQL Server服务器

i := 0;

j := dwEntriesRead;

while i < j do

begin

if pCurSvrInfo = nil then

Break;



with AList do

Add(pCurSvrInfo^.sv100_name);



Inc(i);

Inc(pCurSvrInfo);

end;

end;

finally

if Assigned(pReturnSvrInfo) then

NetApiBufferFree(pReturnSvrInfo);

end;

except

Result := False;

end;

end;

改成动态的如下:
type
NET_API_STATUS = DWORD;
PServerInfo100 = ^TServerInfo100;
_SERVER_INFO_100 = record
sv100_platform_id: DWORD;
sv100_name: LPWSTR;
end;

{$EXTERNALSYM _SERVER_INFO_100}
TServerInfo100 = _SERVER_INFO_100;
SERVER_INFO_100 = _SERVER_INFO_100;
{$EXTERNALSYM SERVER_INFO_100}

TNetApiBufferAllocate = function(ByteCount: DWORD; var Buffer: Pointer): NET_API_STATUS;
TNetServerEnum= function(ServerName: LPCWSTR; Level: DWORD; var BufPtr: Pointer;
PrefMaxLen: DWORD; var EntriesRead: DWORD; var TotalEntries: DWORD;
ServerType: DWORD; Domain: LPCWSTR; ResumeHandle: PDWORD): NET_API_STATUS;
TNetApiBufferFree= function(Buffer: Pointer): NET_API_STATUS;

const
NERR_Success = 0;
MAX_PREFERRED_LENGTH = DWORD(-1);
SV_TYPE_SQLSERVER = $00000004;
function GetSQLServerList(AList: TStrings; pwcServerName: PWChar = nil;pwcDomain: PWChar = nil): Boolean;
var
NetAPIStatus: DWORD;
dwLevel: DWORD;
pReturnSvrInfo: Pointer;
dwPrefMaxLen: DWORD;
dwEntriesRead: DWORD;
dwTotalEntries: DWORD;
dwServerType: DWORD;
dwResumeHandle: PDWORD;
pCurSvrInfo: PServerInfo100;
i, j: Integer;
NetApiBufferAllocate : TNetApiBufferAllocate;
NetServerEnum : TNetServerEnum;
NetApiBufferFree : TNetApiBufferFree;
LibHandle:THandle;
begin
Result := True;
try
dwLevel := 100;
pReturnSvrInfo := nil;
dwPrefMaxLen := MAX_PREFERRED_LENGTH;
dwEntriesRead := 0;
dwTotalEntries := 0;
dwServerType := SV_TYPE_SQLSERVER; //服务器类型
dwResumeHandle := nil;
try
LibHandle := LoadLibrary(pchar('netapi32.dll'));
if LibHandle <> 0 then begin
NetApiBufferAllocate := GetProcAddress(LibHandle, 'NetApiBufferAllocate');
if @NetApiBufferAllocate <> nil then
NetApiBufferAllocate(SizeOf(pReturnSvrInfo), pReturnSvrInfo) //执行到此处出错,请大家帮忙看看是什么原因
else try
NetServerEnum := GetProcAddress(LibHandle, 'NetServerEnum');
if @NetServerEnum <> nil then begin
NetAPIStatus := NetServerEnum(pwcServerName, dwLevel, pReturnSvrInfo,
dwPrefMaxLen, dwEntriesRead, dwTotalEntries, dwServerType, pwcDomain,
dwResumeHandle);
if ((NetAPIStatus = NERR_Success) or (NetAPIStatus = ERROR_MORE_DATA)) and
(pReturnSvrInfo <> nil) then
begin
pCurSvrInfo := pReturnSvrInfo;
// 循环取得所有SQL Server服务器
i := 0;
j := dwEntriesRead;
while i < j do
begin
if pCurSvrInfo = nil then
Break;
with AList do
Add(pCurSvrInfo^.sv100_name);
Inc(i);
Inc(pCurSvrInfo);
end;
end;
end;
finally
if Assigned(pReturnSvrInfo) then begin
NetApiBufferFree := GetProcAddress(LibHandle, 'NetApiBufferFree');
if @NetApiBufferFree <> nil then
NetApiBufferFree(pReturnSvrInfo);
end;
FreeLibrary(LibHandle);
end;
end;
Finally
FreeLibrary(LibHandle);
end;
except
Result := False;
end;
end;
 
难道静态调用不会出错?
NetApiBufferAllocate(SizeOf(pReturnSvrInfo), pReturnSvrInfo);SizeOf(pReturnSvrInfo) = SizeOf(Pointer) = 4,只分配了4个字节哦,而后面的调用dwLevel := 100;NetServerEnum要求传入的pReturnSvrInfo是SERVER_INFO_100结构指针哩
 
不会错,你可以运行看一下。
 
诚挚邀请您加入我的群,共同探讨delphi的问题,群号:4963281,谢谢!
 
后退
顶部