关于CreateThread的基础问题 ( 积分: 50 )

  • 主题发起人 主题发起人 rsina
  • 开始时间 开始时间
R

rsina

Unregistered / Unconfirmed
GUEST, unregistred user!
小弟最近写一个程序,用到 CreateThread 传递一个结构,结果发现有两个问题:

1、最后一个结构成员总传递失败,显示为乱码,但是如果使用逐个填充就没问题;
2、结构成员必须是pchar类型,如果使用string类型也会失败;

这是为什么啊?

//======================================================
type
msg = record
caption: pchar;
str: pchar;
end;
Pmsg=^msg;

implementation

{$R *.dfm}

function test(pp: Pmsg): DWORD
stdcall;
begin
messagebox(0,pchar(pp.caption), pchar(pp.str), 0);
result := 0;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
Threadid: dword;
Parameter: Pmsg;
mymsg: msg;
begin
mymsg.caption := '1';
mymsg.str := '2';
messagebox(0,pchar(mymsg.caption), pchar(mymsg.str), 0);
parameter := @mymsg
//这种方法导致mymsg.str 显示为乱码

{ //如果使用以下方法就没问题
getmem(Parameter, Sizeof(Parameter));
Parameter.caption := '1';
parameter.str := '2';
}
CreateThread(Nil, 0, @test, Parameter, 0, Threadid);
end;
 
我认为是这样:mymsg是在TForm1.Button1Click中的局部变量,所以当TForm1.Button1Click执行完后他就被自动释放掉了,所以如果test这个线程去读取里面的数据就很难说读到什么东西了,事实上,在我的机器上我测试了楼主的代码,两种方法均没有出现任何问题,但是,当我把test改为:
function test(pp: Pmsg): DWORD
stdcall;
begin
Sleep(1000);
messagebox(0,pchar(pp.caption), pchar(pp.str), 0);
result := 0;
end;
问题就出现了,有时显示乱码,有时还会出错。
所以,把mymsg: msg;定义为全局变量问题就没有了
 
PChar类型传递的是指针,在将一个string类型的变量转换位Pchar类型时实际上是传递的string变量的地址,如果该string变量的为局部变量,当Button1Click执行完成后就被自动释放掉了,该指针所指向数据,应该是不确定的。
 
type
msg = record
caption: pchar;
str: pchar;
end;
Pmsg=^msg;

msg都是指针,指针长度4.
sizeof(msg)=8 bit.
而字符=16 bit 宽字符 32bit.

解决办法:
new分配空间.或者
getmem(Parameter, 2*Sizeof(char));//你的2个字符
//没环境测试,按理是这样的
 
CreateThread 是api,所以要用pchar。而mymsg: msg是基本类型,是在堆栈里,出了方法就没有了。而Parameter: Pmsg;是指针,出了方法仍然在。
 
后退
顶部