想用一个结构作为变量传递,为什么会报错??? ( 积分: 100 )

  • 主题发起人 主题发起人 sxwy
  • 开始时间 开始时间
S

sxwy

Unregistered / Unconfirmed
GUEST, unregistred user!
下面想用一个指针引用一个结构传递参数,但是在赋初值的时候会报错,不知为什么??
//结构如下:
type
communit=record
revdata:string;//接收到的字节字符串
com:string;//通信端口号
hcom:longint;//这个COM口打开成功的线程号
end;
communitpointer = ^communit;//用来传递参数
下面是引用:
VAR tmp:communitpointer ;
COM_WATCH:THANDLE;
begin
getmem(tmp,sizeof(tmp));
with tmp^ do //将COMINFO的参数用CREATETHREAD传递到串口监视程序里去
begin
hcom:=cominfo.hcom ;
revdata:='';
com:='COM1';//这里系统会报错,?为什么,无论如何都不能对两个STRING变量赋值.
end;//要么可以赋COM:='COM1',但不能赋REVDATA='',要么可以赋REVDATA:='',但是不能
//赋COM:='COM1';
com_watch:=createthread(nil,0,@commwatch,tmp,0,0);把TMP作为参数传递到@commwatch线程。
 
下面想用一个指针引用一个结构传递参数,但是在赋初值的时候会报错,不知为什么??
//结构如下:
type
communit=record
revdata:string;//接收到的字节字符串
com:string;//通信端口号
hcom:longint;//这个COM口打开成功的线程号
end;
communitpointer = ^communit;//用来传递参数
下面是引用:
VAR tmp:communitpointer ;
COM_WATCH:THANDLE;
begin
getmem(tmp,sizeof(tmp));
with tmp^ do //将COMINFO的参数用CREATETHREAD传递到串口监视程序里去
begin
hcom:=cominfo.hcom ;
revdata:='';
com:='COM1';//这里系统会报错,?为什么,无论如何都不能对两个STRING变量赋值.
end;//要么可以赋COM:='COM1',但不能赋REVDATA='',要么可以赋REVDATA:='',但是不能
//赋COM:='COM1';
com_watch:=createthread(nil,0,@commwatch,tmp,0,0);把TMP作为参数传递到@commwatch线程。
 
getmem(tmp,sizeof(communit));

这样看看

type
communit=record
revdata:string;//接收到的字节字符串
com:string;//通信端口号
hcom:longint;//这个COM口打开成功的线程号
end;
communitpointer = ^communit;//用来传递参数
VAR tmp:communitpointer ;
COM_WATCH:THANDLE;
begin
getmem(tmp,sizeof(communit));
with tmp^ do begin
hcom := cominfo.hcom ;
revdata:='';
com:='COM1';
end;
com_watch:=createthread(nil,0,@commwatch,tmp,0,0);
end.
 
改成这样呢:
var
tmp : CommUnit; //tmp定义成结构变量而非结构指针变量
Com_Watch : THandle;
begin
with tmp do
begin
hcom := cominfo.hcom;
revdata := '';
com := 'COM1';
end;
com_watch:=createthread(nil,0,@commwatch,@tmp,0,0);//这里改成取变量tmp的地址
end;
 
二楼的大哥还是不行,运行到第二个STRING变量赋值时出错,三楼的大哥可以赋值,但这样的话在以下的串口监视过程里就取不到所要的结构参数,这个REVDATA是我后来加上在结构里加的.
procedure commwatch (var tmpcominfo:communit);stdcall//串口通信监视线程
var dwevtmask,dwtranser:dword;
postmsgflag:boolean;
overlapped:toverlapped;
tmp:c_result;
begin
fillchar(overlapped,sizeof(overlapped),0);
overlapped.hEvent :=createevent(nil,true,false,nil);
if overlapped.hEvent =null then
begin
showmessage('overlappen.event create error');//0,'overlapped.event create error','notice',[mbok]);
exit;
end;
//进入串口监视状态,直到receive为false为止
while(receive) do
begin
dwevtmask:=0;
if not WaitCommEvent(tmpcominfo.hcom,dwevtmask,@overlapped) then
begin
if ERROR_IO_PENDING=GetLastError then
waitforsingleobject(overlapped.hEvent,infinite); //可以用上面getoverlappedresult函数代替此windows信号等待功能(waitforsingleject())
end;
//-------------------串口读事件发步消息
if ((dwevtmask and ev_rxchar)=ev_rxchar) then
begin
revcomdatasxw(tmpcominfo);
if (not postmsgflag) then
begin
messagebox(0,'postmessage error','notice',mb_ok);
exit;
end;
end;
end;
closehandle(overlapped.hEvent );//如果receive为FALSE就关闭重叠事件
end;
 
不好意思,看错了,string确实不行,因为至少不知道要给它分配多少大小的内存,所以可以修改成char的数组,或者执行string的长度,比如string[20]只有的方式,因为string可以理解成一个动态数组,这样行吗?写串口可以改造一下spcomm的代码,省力许多
 
record中建议不要用string,因为string本身只是指针,4字节,指向一个内存地址,所以这样会很容易报错.建议用shortstring,shortstring是限长的字符串,最长255个字符,这样就可以满足你的需求了.如果你知道这个字符串的最大值,可以这样定义
type
myrec=record
str1: string[15];
str2: string[22];
end;
方括号里面的字符就表示这个字符串的长度.
 
现在看可能不是能不能传递的问题,我现在如果只传递一个STRING参数,那么就正常.为什么这个结构里不能传递两个参数呢.
结构里这两个参数,
revdata:STRING;
com:STRING;
在初始化的时候只能给一个赋值.同时赋两个就出错,真是怪事.而且赋值一个给变量COM或者REVDATA的话,在以后的过程里使用也正常.并不是说在结构里不能用STRING传递参数.
revcomdata.revdata :=revcomdata.revdata +hextostring(temphex);这是我用结构里的REVDATA来接收数据。正常。
 
wangergulei,你好,按你的方法不会报错,但是将TMP的址址作为参数传到线程commwatch后,怎么将结构TMP里的数据取出来呢.
将线程COMMWQTCH改为下面:
com_watch:=createthread(nil,0,@commwatch,@tmp,0,0);//这里改成取变量tmp的地址
procedure commwatch1 (var tmpcominfo:pointer);stdcall//用指针作为参数传递
BEIN
这里应该怎么将@TMP的结构数据取出来呢?
END;
 
赞同结构体里避免使用string,应该使用char数组。string类型数据取到的字符串的地址,可以试着再增加一个string类型的变量在结构体内,应该只有一个string可以取到,其他不能用。
 
我现在不用GETMEM,而用NEW就可以了.
 
*******************************************************
wangergulei,你好,按你的方法不会报错,但是将TMP的址址作为参数传到线程commwatch后,怎么将结构TMP里的数据取出来呢.
将线程COMMWQTCH改为下面:
com_watch:=createthread(nil,0,@commwatch,@tmp,0,0);//这里改成取变量tmp的地址
procedure commwatch1 (var tmpcominfo:pointer);stdcall//用指针作为参数传递
BEIN
这里应该怎么将@TMP的结构数据取出来呢?
END;
*************************************************************
采用下面这个方法试试:
var
Buffer:Array [1..2048] of Char;
CopyMemory(@tmpcominfo,@Buffer[1],SizeOf(tmp));
 
多人接受答案了。
 
后退
顶部