请教一个内存访问出错的简单问题 (50分)

  • 主题发起人 主题发起人 base7
  • 开始时间 开始时间
B

base7

Unregistered / Unconfirmed
GUEST, unregistred user!
有这样一个函数(网上抄来的):
代码:
function SendMsg(Toh,Msg:string):integer;
var
  ToName: array [0..63] of WideChar;
  WMsgText: array [0..999] of WideChar;
  MsgLen, I:integer;
begin
  for I := 0 to 63 do ToName[i] := #0;
  for I := 0 to 999 do WMsgText[i] := #0;
  StringToWideChar(Toh, ToName, 64);
  StringToWideChar(Msg, WMsgText, 1000);
//  MsgLen := Length(Msg);
  Result:=NetMessageBufferSend(nil,ToName,nil,@WMsgText,MsgLen);
end;

我的主程序中调用了这个函数后,只要进行任何一步其他的操作,如:
btnOK.Enable := True;
时就会产生access violation的错误,个人认为应该是SendMsg函数中写了(或读了)未开辟的内存区
可是怎么改也不行,诸位熟悉Win编程和DLL调用的大侠能帮帮忙吗?(调用了netapi32.dll)
 
不是吧?有熟悉的大侠能吱一声吗?
 
看看NetMessageBufferSend的申明,我在Delphi5中找不到。怀疑是@WMsgText不用加@。
看了申明才能确定。。
 
NetMessageBufferSend是netapi32.dll中的函数,当然直接找不到
WMsgText不加@我早就试过了,不行啊
代码:
NET_API_STATUS NetMessageBufferSend(
    LPTSTR servername,	
    LPTSTR msgname,	
    LPTSTR fromname,	
    LPBYTE buf,	
    DWORD buflen	
   );
 
是用BDE吗?
 
PWideChar 必须先开一个内存空间嘛。
举个例子:
var
pPWChar: PWideChar;
pLen: Integer;
pStr: string;
begin
pLen := Length(yourMsg) + 1;
AllowMem(pPWChar, pLen);
try
StringToWideChar(pStr, pPWChar, pLen);
finally
FreeMem(pPWChar);
end;
end;


end;
function SendMsg(Toh,Msg:string):integer;
var
ToName: array [0..63] of WideChar;
WMsgText: array [0..999] of WideChar;
MsgLen, I:integer;
begin
for I := 0 to 63 do ToName := #0;
for I := 0 to 999 do WMsgText := #0;
StringToWideChar(Toh, ToName, 64);
StringToWideChar(Msg, WMsgText, 1000);
// MsgLen := Length(Msg);
Result:=NetMessageBufferSend(nil,ToName,nil,@WMsgText,MsgLen);
end;
 
5291大侠,能说得详细点吗?
你那的AllowMem是不是就是GetMem?我的程序改成了这样:
代码:
function SendMsg(Toh,Msg:string):integer;
var
  ToName, WMsgText: PWideChar;
  MsgLen, pLen: Integer;
begin
  pLen := Length(Msg) + 1;
  GetMem(WMsgText, pLen);
  StringToWideChar(Msg, WMsgText, pLen);
  pLen := Length(Toh) + 1;
  GetMem(Toname, pLen);
  StringToWideChar(Toh, Toname, pLen);
  MsgLen := Length(Msg);
  Result:=NetMessageBufferSend(nil,ToName,nil,@WMsgText,MsgLen);
  FreeMem(WMsgText);
  FreeMem(Toname);
end;
可是问题照旧?!:(
 
function SendMsg(Toh,Msg:string):integer;
var
ToName: LPTSTR;
WMsgText: LPTSTR;
MsgLen, I:integer;
begin
New(ToName),New(WMsgText);//为什么不用NEW来分配空间呢?
MsgLen:=Length(Msg)+1;
StrPCopy(ToName,Toh);
StrPCopy(WMsgText,Msg);
Result:=NetMessageBufferSend(nil,ToName,nil,WMsgText,MsgLen);
end;

试试吧,用NEW的空间是自动释放,所以很方便.
 
function SendMsg(Toh,Msg:string):integer;
var
ToName, WMsgText: PWideChar;//应该用PWideString;
MsgLen, pLen: Integer;
begin
pLen := Length(Msg) + 1;
GetMem(WMsgText, pLen);
StringToWideChar(Msg, WMsgText, pLen);
pLen := Length(Toh) + 1;
GetMem(Toname, pLen);
StringToWideChar(Toh, Toname, pLen);
MsgLen := Length(Msg);
Result:=NetMessageBufferSend(nil,ToName,nil,@WMsgText,MsgLen);//WMsgText是指
针,所以不要加@,加了反而是AV.
FreeMem(WMsgText);
FreeMem(Toname);
end;


Result:=NetMessageBufferSend(nil,ToName,nil,@WMsgText,MsgLen);//两个都要加'@',
Result:=NetMessageBufferSend(nil,@ToName,nil,@WMsgText,MsgLen);

 
to BeginDelphi:
我的程序现在这样了:
代码:
var
  ToName: LPTSTR;
  WMsgText: LPTSTR;
  MsgLen, I:integer;
begin
New(ToName);
New(WMsgText);
MsgLen:=Length(Msg)+1;
StrPCopy(ToName,Toh);
StrPCopy(WMsgText,Msg);
Result:=NetMessageBufferSend(nil,@ToName,nil,@WMsgText,MsgLen);
end;
可是还有access violation呀
还有,PwideString如何赋值呢?在最后的NetmessageBufferSend中是不是还得加@?

 
我使用是没有问题啊,
 
哦,还有很重要的一点,NetMessageBufferSend的声明被改成这样的:
代码:
NET_API_STATUS NetMessageBufferSend(
    servername:PwideChar ;	
    msgname:PwideChar ;	
    fromname:PwideChar ;	
    buf:PwideChar ;
    var buflen: Integer
   );
会不会和这个有关系呢?
 
to 张无忌:
你在调用这个函数后还有其他过程吗?
比如:button1.enabled := False 之类的
如果没有其他操作,的确一切正常,可是...
 
我也碰到过这个问题,我的办法是不做其他操作,我也想知道原因,
还有我试了你等NetMessageBufferSend发送完了,再做其他操作就
没有问题了
 
PWideChar可以这么转。

var MyStr:PWideChar;
MyAnsiStr:string;
begin
MyAnsiStr:='MyAnsiStr';
MyStr:=StringToOleStr(MyAnsiStr);

end;
 
>>张无忌
可是什么时候是NetMessageBufferSend发送完了呢?
这个函数执行之后有一个返回参数,也就是错误类型,这个时候应该算发送完了吧?
可是不行啊...
>>BeginDelphi
谢谢你,可是我真的快绝望了...
 
系统问题?
 
谢谢大家
我修改了声明,结果成功了
function NetMessageBufferSend(servername : LPCWSTR; MsgName : LPCWSTR;
FromName : LPCWSTR; Buf : Pointer; BufLen : DWORD): DWORD; stdcall;
 
后退
顶部