Dll调用问题,分配内存出错

xiaofeng_cxy 2007-04-13 11:47:17
用一个Dll封装了几个IpHlpApi.dll的函数
然后进行调用时,会报内存ReadError
但如果用exe将封装单元引入,则完全正常,有没有大牛能帮我分析一下???

DllUnit

type
PArpRec = ^TArpRec;
TArpRec = record
Ip: string[15];
Index: Integer;
Mac: array[0..7] of Byte;
end;

function _refreshArpTable: Boolean;
var
i, j: Integer;
dwResult, dwSize: DWORD;
p_arptable: PMibIpNetTable;
p_arprow: PMibIpNetRow;
szTemp: string;
parp: PArpRec;
begin
szTemp := '';
p_arptable := nil;

for i := 0 to _arpTable.Count - 1 do
FreeMem( PArpRec( _arpTable.Objects[i] ) );
_arpTable.Clear;
dwSize := 0;
dwResult := GetIpNetTable(p_arptable, dwSize, False);
// if p_arptable = nil then
//报错的就是这行
p_arptable := AllocMem(dwSize);

try
if NO_ERROR = GetIpNetTable(p_arptable, dwSize, False) then
begin
for i := 0 to p_arptable.dwNumEntries - 1 do
begin
p_arprow := AllocMem(SizeOf(TMibIpNetRow));
ZeroMemory(p_arprow, SizeOf(TMibIpNetRow));
Move(p_arptable^.table[i], p_arprow^, SizeOf(TMibIpNetRow));
parp := AllocMem( SizeOf( TArpRec) );
parp^.Ip := inet_ntoa( in_addr( p_arprow^.dwAddr ) );
parp^.Index := p_arprow^.dwIndex;
for j := 0 to 5 do
parp^.Mac[j] := p_arprow^.bPhysAddr[j];

_arpTable.AddObject(parp^.Ip, TObject( parp ));
end;
end;
finally
// if p_arptable <> nil then
FreeMem(p_arptable);
end;
end;

错误信息:
Access violation at address 014663E2 in module 'Arpwatch.dll' write of address 0147FDCC

在线等待,不胜感谢!!!
...全文
259 点赞 收藏 9
写回复
9 条回复
xiaofeng_cxy 2007年04月14日
最终找出原因
由于使用了fastmm4,不知道是否fastmm对于dll存在着内存管理方面的问题?会引起分配内存报错,但在exe中都很正常.....
将所有工程文件中的第一行加上sharemem,只能在发布时,连borlandmm.dll一起了
回复 点赞
xiaofeng_cxy 2007年04月13日
另外,在library Arpwatch中引用了FastMM4,未引用ShareMem
回复 点赞
xiaofeng_cxy 2007年04月13日
是另外一个函数调用_refreshArpTable,
function aw_CheckArpTable(AArpTable: string): string; stdcall;

refreshArpTable为单元内函数,且也加过stdcall试过了
exports
aw_CheckArpTable index 1;
回复 点赞
HsWong 2007年04月13日
有无exports接口,有无用Stdcall?
回复 点赞
xiaofeng_cxy 2007年04月13日
问题是相同的单元,在DLL中,就会报错
在Exe中则一点错误都没有!!
回复 点赞
xiaofeng_cxy 2007年04月13日
GetIpNetTable需要调用两次,实际上应该是这样
GetIpNetTable(nil, dwSize, False);
p_arptable := AllocMem(dwSize);

GetIpNetTable(p_arptable, dwSize, False);

第一次,获取Size大小
第二次,才获取真正的arp table

GetIpNetTable是IpHlpApi.dll里面的函数
回复 点赞
xiaocai800322 2007年04月13日
我认为实际出错的是这行
dwResult := GetIpNetTable(p_arptable, dwSize, False);
这里面的指针没有分配空间就用了,如果没有猜错的话GetIpNetTable这个函数应该是DLL文件里面写的

如果前面不错,下面两行不应该报错
if p_arptable = nil then
p_arptable := AllocMem(dwSize);
回复 点赞
xiaocai800322 2007年04月13日
这不会是别的问题,一定是指针没有分配空间就用或者其他指针使用不当出的问题
回复 点赞
yf110 2007年04月13日
需要引用ShareMem,并且放在第一个位置
回复 点赞
发动态
发帖子
Windows SDK/API
创建于2007-08-02

797

社区成员

2.2w+

社区内容

Delphi Windows SDK/API
社区公告
暂无公告