求助有关delphi对象指针的问题

stevel 2008-09-26 03:21:12

//异步传送参数组
procedure TFormMain.ProcessFileTransferOutput();
var
Parameters: TStringlist;

begin
Parameters:=TStringList.Create;

Parameters.Add('1'); //操作类型
Parameters.Add('ProcessFileTransferOutput Ok!'); //操作参数

Asynchronous(Parameters,TFormMain.ProcessFileTransferOutput); //异步执行ProcessFileTransferOutput过程

end;


//处理参数过程
procedure TFormMain.ProcessFileTransferOutput(PData:Pointer);
var
Parameters:TStringlist;
begin
Parameters:=PData;

case StrToInt(Parameters[0]) of
1: begin
AddLineStr(Parameters[1],1,true);
end;

2: begin

end;
end;

Parameters.Free; //这句过后,程序显示Invalid pointer operation对话框,为什么啊??

end;

...全文
156 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
stevel 2008-09-26
  • 打赏
  • 举报
回复
多谢大家,我找到原因了,是我看错了地方。上面有些回答者带有些疑问,我奉上完整的测试例子,给大家调试下。

//窗体上放置一个按钮,然后把下面代码,覆盖整个窗体代码。


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

const
MM_ASYNCHRONOUS = WM_USER + 1;

type DataMethod=procedure(PData:Pointer) of object;


type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure ProcessAsynchronous(var Message: TMessage); message MM_ASYNCHRONOUS;

procedure ProcessFileTransferOutput(); overload;
procedure ProcessFileTransferOutput(PData:Pointer); overload;

end;


var
Form1: TForm1;

procedure Asynchronous(Method:DataMethod;PData:Pointer);

type
TAThread = class(TThread)
public
procedure Execute; override;
end;


implementation

{$R *.dfm}

procedure TAThread.Execute;
begin
form1.ProcessFileTransferOutput;
Terminate;
end;

procedure Asynchronous(Method:DataMethod;PData:Pointer);
type PMethod=^TMethod;
var
AMethod:PMethod;
begin

New(AMethod);

AMethod.Code:=TMethod(Method).Code;
AMethod.Data:=TMethod(Method).Data;

PostMessage(Form1.Handle,MM_ASYNCHRONOUS,Integer(AMethod),Integer(PData));

end;

procedure TForm1.ProcessAsynchronous(var Message: TMessage);
type PMethod=^TMethod;
var
AMethod: PMethod;
begin

AMethod := PMethod(message.WParam);

DataMethod(AMethod^)(Pointer(Message.LParam));


//实在不知道为什么不简单忽略这个错误,哪位知道告知一下。。
{$I-}
try
Dispose(Pointer(Message.LParam));
finally
end;
{$I+}
if IOResult<>0 then
ShowMessage('Error Dispose!');

Dispose(AMethod);

end;


//异步传送参数组
procedure TForm1.ProcessFileTransferOutput();
var
Parameters: TStringlist;

begin
Parameters:=TStringList.Create;

Parameters.Add('1'); //操作类型
Parameters.Add('ProcessFileTransferOutput Ok!'); //操作参数

Asynchronous(self.ProcessFileTransferOutput,Parameters); //异步执行ProcessFileTransferOutput过程

end;

//处理参数过程
procedure TForm1.ProcessFileTransferOutput(PData:Pointer);
var
Parameters:TStringlist;
begin
Parameters:=PData;

case StrToInt(Parameters[0]) of
1: begin
ShowMessage(Parameters[1]);
end;

2: begin

end;
end;

//这句是不需要了,在ProcessAsynchronous里会释放
Parameters.Free; //这句过后,程序显示Invalid pointer operation对话框,为什么啊??


end;


procedure TForm1.Button1Click(Sender: TObject);
var
Athread:TAThread;
begin
Athread:=TAThread.Create(False);
Athread.Execute;
end;

end.



Harryfin 2008-09-26
  • 打赏
  • 举报
回复
没释放对象一般情况是不会报invalid pointer operation的,我见过报这个错的通常是两种情况:

1、进程间传了字符串,但是该字符串的内存不共享
2、带有引用计数功能的接口实现释放时引用计数值不为0
Harryfin 2008-09-26
  • 打赏
  • 举报
回复
我估计你的程序肯定跨了DLL?然后从一个DLL(exe)把字符串传递到了另外一个DLL中。

这里说的传递,不单是指你显式地在DLL导出函数中传递才会这样,你传对象,对象中包含了字符串,也是同样的情况(你现在传了StrinngList)

解决的方法也很简单,两个DLL(exe)都在工程文件中第一个use的位置加上ShareMem即可,发布时带上Borlndmm.DLL。
kampan 2008-09-26
  • 打赏
  • 举报
回复
procedure TFormMain.ProcessFileTransferOutput();
var
Parameters: TStringlist;

begin
Parameters:=TStringList.Create;

Parameters.Add('1'); //操作类型
Parameters.Add('ProcessFileTransferOutput Ok!'); //操作参数

Asynchronous(Parameters,TFormMain.ProcessFileTransferOutput); //异步执行ProcessFileTransferOutput过程
Parameters.Free;

end;
suton 2008-09-26
  • 打赏
  • 举报
回复
可以传字符串
传递的时候:
Asynchronous(PChar(Parameters.Text),TFormMain.ProcessFileTransferOutput);

函数内:
pData: PChar;

Parameters.Text:=PData;


至于你的疑惑:
研究你的代码:

procedure TFormMain.ProcessFileTransferOutput();
var
Parameters: TStringlist; //Parameters定义在这里,就是一个局部变量,这个过程结束后,这个对象就释放了.
//我个人猜想:变量的定义,只是定义"占位符"的过程,也就是说,告诉系统,从这个指针所指的地址开始,
//后面某段空间,将在Parameters调用Create的时候,使用. 占位嘛,就是占据一定数量的数据位.
//如果再分配空间,请不要采用这段空间.
//虽然这个过程结束时,Parameters释放了,但是,内存空间里面的值,还是没有变.还是释放前的值.

begin
Parameters:=TStringList.Create;

Parameters.Add('1'); //操作类型
Parameters.Add('ProcessFileTransferOutput Ok!'); //操作参数

Asynchronous(Parameters,TFormMain.ProcessFileTransferOutput); //异步执行ProcessFileTransferOutput过程

end;


//处理参数过程
procedure TFormMain.ProcessFileTransferOutput(PData:Pointer);
var
Parameters:TStringlist;
begin
Parameters:=PData; //这里,通过指针获得原来Parameter的地址,可能因为内存空间的值,刚好没有被系统重新分配给其他变量
//所以通过Parameters[i]来访问某个域访问内的内存值,还是存在的.
case StrToInt(Parameters[0]) of
1: begin
AddLineStr(Parameters[1],1,true);
end;

2: begin

end;
end;

Parameters.Free; //这句过后,程序显示Invalid pointer operation对话框,为什么啊??

//这里,你开始只是赋值一个地址而已,并没有创建对象,调用free,估计不行. 不如:Parameters := nil;
end;



以上纯属个人胡乱分析,哈哈,不知道是不是这样.
DreamMan81 2008-09-26
  • 打赏
  • 举报
回复
Parameters:=PData;
能这样赋值吗?
手指风 2008-09-26
  • 打赏
  • 举报
回复
坚持谁创建谁释放的原则.
fangsp 2008-09-26
  • 打赏
  • 举报
回复
Parameters := nil 
Parameters.Free

5,385

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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