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

在线等待,不胜感谢!!!
...全文
348 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
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,并且放在第一个位置

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧