我做了一个DLL,他的主要工作是向串口发送数据,并得到串口的数据。它是不能使用界面的。我用了控件SPCOMM。

时间:2022-11-16 19:25:30
发送都很正常,可是接受的时候总是不能得到串口的数据(已经证实,串口已经发送了数据),请问那位大侠能给一段这个没有界面使用SPCOMM的例子呢???小弟谢谢了!!!!!

7 个解决方案

#1


在动态库的接收里,把接收的数据些到文件中,再查看文件,看看事不是没接收到。

#2


根本就不触发接受事件我的代码是这样写的:
type
  TTemp_Comm = class (TComm)
    procedure CommReceiveData(Sender: TObject; Buffer: Pointer;
      BufferLength: Word);
    public
      procedure InstallIC_Form(Comm_Temp:TComm);
  end;
function Install_IC(Comm1:TComm):Boolean;stdcall;  

...

function Install_IC(Comm1:TComm):Boolean;stdcall;
var
  Com_Tem:TComm;
begin
  EventFlag:=0;
  Com_Tem:=TComm.Create(nil);
  Com_Tem:=Comm1;
  Com_Tem.OnReceiveData:=Comm_Test.CommReceiveData;
  Comm_Test.InstallIC_Form(Com_Tem);
  Com_Tem.Free;
  Result:=ResultFlag;
end;

...
//发送
procedure TTemp_Comm.InstallIC_Form(Comm_Temp:TComm);
var
  Search_Con:String;
  Send:Boolean;
begin
  if Comm_Temp<>NIL then
  begin
    Search_Con:=#$5A#$4A;
    Sleep(50);
    Send:=Comm_Temp.WriteCommData(Pchar(Search_Con),Length(Search_Con));
    if not Send then
    begin
      ResultFlag:=false;
    end;
  end;
end;
//接受
procedure TTemp_Comm.CommReceiveData(Sender: TObject; Buffer: Pointer;
  BufferLength: Word);
var
  PointCon:String;
  RevCon:String;
  HRevCon:String;
  GetStrLen:Integer;//得到帐号的长度
  I:Integer;
  Begin_Str,End_Str:String;//帐号的前面和后面字符
begin
  PointCon:=String(Buffer);
  RevCon:=Copy(PointCon,0,BufferLength);
  HRevCon:=ConvertString(RevCon);
  case EventFlag of
  0: 
  begin
    if HRevCon='4A5A' then
    begin
      Application.MessageBox('OK','ok',mb_ok);
      ResultFlag:=true;
    end
    else
    begin
      ResultFlag:=false;
    end;
  end;
  end;
end;
我发现发送都是正常的,但是就是不能触发接受事件!!!!!!!!
请大侠帮助!!!

#3


把Com_Tem定义为全局变量试一下。

#4


function Install_IC(Comm1:TComm):Boolean;stdcall;
var
  Com_Tem:TComm;
begin
  EventFlag:=0;
  Com_Tem:=TComm.Create(nil);
  Com_Tem:=Comm1;
  Com_Tem.OnReceiveData:=Comm_Test.CommReceiveData;
  Comm_Test.InstallIC_Form(Com_Tem);
  Com_Tem.Free;
  Result:=ResultFlag;
end;
主要是此函数的问题,前面赋值后面释放,把变量改为全局变量,把创建、释放放到另外函数中执行。

#5


我试了一下,但是一下修改了。
现在接受事件可以被触发了,但是在运行Install_IC函数以后才能触发接受事件。
可是这样以来和我的DLL的目的是不一致的呀,我本来想调用这个DLL,我的DLL可以想COM发送消息,并且将COM返回的消息接受并判断后返回给调用者。
我的代码是这样的:
var
  Form1: TForm1;
  Comm_Temp1:TComm;
.....

function Install_IC(Comm1:TComm):Boolean;stdcall;
begin
  Comm_Temp1:=TComm.Create(nil);
  ResultFlag:=false;
  EventFlag:=0;
  Comm_Test.InstallIC_Form(Comm1);
  Result:=ResultFlag;
end;

...
procedure TTemp_Comm.InstallIC_Form(Comm_Temp:TComm);
var
  Search_Con:String;
  Send:Boolean;
begin
  Comm_Temp.OnReceiveData:=CommReceiveData;
  if Comm_Temp<>NIL then
  begin
    Search_Con:=#$AA#$BB;
    Sleep(50);
    Send:=Comm_Temp.WriteCommData(Pchar(Search_Con),Length(Search_Con));
    if not Send then
    begin
      ResultFlag:=false;
    end;
  end;
end;

....
procedure TTemp_Comm.CommReceiveData(Sender: TObject; Buffer: Pointer;
  BufferLength: Word);
var
  PointCon:String;
  RevCon:String;
  HRevCon:String;
  GetStrLen:Integer;//得到帐号的长度
  I:Integer;
  Begin_Str,End_Str:String;//帐号的前面和后面字符
begin
  PointCon:=String(Buffer);
  RevCon:=Copy(PointCon,0,BufferLength);
  HRevCon:=Form1.ConvertString(RevCon);
  case EventFlag of
  0: 
  begin
    if HRevCon='1122' then
    begin
      ResultFlag:=true;
    end
    else
    begin
      ResultFlag:=false;
    end;
  end;
  end;
  Comm_Temp1.free;
end;


#6


自己顶

#7


1:现在接受事件可以被触发了,但是在运行Install_IC函数以后才能触发接受事件。

在Install_IC中创建了TComm的一个实例Comm_Temp1,所以只能在运行Install_IC函数后才能触发接收事件。

2: Comm_Temp1.free;不应该放在CommReceiveData中,除非你的程序只接收一次数据。我一般的做法是在用户关闭串口或是结束程序时释放端口;

3:为什么不把串口的开、关放在DLL中?

#1


在动态库的接收里,把接收的数据些到文件中,再查看文件,看看事不是没接收到。

#2


根本就不触发接受事件我的代码是这样写的:
type
  TTemp_Comm = class (TComm)
    procedure CommReceiveData(Sender: TObject; Buffer: Pointer;
      BufferLength: Word);
    public
      procedure InstallIC_Form(Comm_Temp:TComm);
  end;
function Install_IC(Comm1:TComm):Boolean;stdcall;  

...

function Install_IC(Comm1:TComm):Boolean;stdcall;
var
  Com_Tem:TComm;
begin
  EventFlag:=0;
  Com_Tem:=TComm.Create(nil);
  Com_Tem:=Comm1;
  Com_Tem.OnReceiveData:=Comm_Test.CommReceiveData;
  Comm_Test.InstallIC_Form(Com_Tem);
  Com_Tem.Free;
  Result:=ResultFlag;
end;

...
//发送
procedure TTemp_Comm.InstallIC_Form(Comm_Temp:TComm);
var
  Search_Con:String;
  Send:Boolean;
begin
  if Comm_Temp<>NIL then
  begin
    Search_Con:=#$5A#$4A;
    Sleep(50);
    Send:=Comm_Temp.WriteCommData(Pchar(Search_Con),Length(Search_Con));
    if not Send then
    begin
      ResultFlag:=false;
    end;
  end;
end;
//接受
procedure TTemp_Comm.CommReceiveData(Sender: TObject; Buffer: Pointer;
  BufferLength: Word);
var
  PointCon:String;
  RevCon:String;
  HRevCon:String;
  GetStrLen:Integer;//得到帐号的长度
  I:Integer;
  Begin_Str,End_Str:String;//帐号的前面和后面字符
begin
  PointCon:=String(Buffer);
  RevCon:=Copy(PointCon,0,BufferLength);
  HRevCon:=ConvertString(RevCon);
  case EventFlag of
  0: 
  begin
    if HRevCon='4A5A' then
    begin
      Application.MessageBox('OK','ok',mb_ok);
      ResultFlag:=true;
    end
    else
    begin
      ResultFlag:=false;
    end;
  end;
  end;
end;
我发现发送都是正常的,但是就是不能触发接受事件!!!!!!!!
请大侠帮助!!!

#3


把Com_Tem定义为全局变量试一下。

#4


function Install_IC(Comm1:TComm):Boolean;stdcall;
var
  Com_Tem:TComm;
begin
  EventFlag:=0;
  Com_Tem:=TComm.Create(nil);
  Com_Tem:=Comm1;
  Com_Tem.OnReceiveData:=Comm_Test.CommReceiveData;
  Comm_Test.InstallIC_Form(Com_Tem);
  Com_Tem.Free;
  Result:=ResultFlag;
end;
主要是此函数的问题,前面赋值后面释放,把变量改为全局变量,把创建、释放放到另外函数中执行。

#5


我试了一下,但是一下修改了。
现在接受事件可以被触发了,但是在运行Install_IC函数以后才能触发接受事件。
可是这样以来和我的DLL的目的是不一致的呀,我本来想调用这个DLL,我的DLL可以想COM发送消息,并且将COM返回的消息接受并判断后返回给调用者。
我的代码是这样的:
var
  Form1: TForm1;
  Comm_Temp1:TComm;
.....

function Install_IC(Comm1:TComm):Boolean;stdcall;
begin
  Comm_Temp1:=TComm.Create(nil);
  ResultFlag:=false;
  EventFlag:=0;
  Comm_Test.InstallIC_Form(Comm1);
  Result:=ResultFlag;
end;

...
procedure TTemp_Comm.InstallIC_Form(Comm_Temp:TComm);
var
  Search_Con:String;
  Send:Boolean;
begin
  Comm_Temp.OnReceiveData:=CommReceiveData;
  if Comm_Temp<>NIL then
  begin
    Search_Con:=#$AA#$BB;
    Sleep(50);
    Send:=Comm_Temp.WriteCommData(Pchar(Search_Con),Length(Search_Con));
    if not Send then
    begin
      ResultFlag:=false;
    end;
  end;
end;

....
procedure TTemp_Comm.CommReceiveData(Sender: TObject; Buffer: Pointer;
  BufferLength: Word);
var
  PointCon:String;
  RevCon:String;
  HRevCon:String;
  GetStrLen:Integer;//得到帐号的长度
  I:Integer;
  Begin_Str,End_Str:String;//帐号的前面和后面字符
begin
  PointCon:=String(Buffer);
  RevCon:=Copy(PointCon,0,BufferLength);
  HRevCon:=Form1.ConvertString(RevCon);
  case EventFlag of
  0: 
  begin
    if HRevCon='1122' then
    begin
      ResultFlag:=true;
    end
    else
    begin
      ResultFlag:=false;
    end;
  end;
  end;
  Comm_Temp1.free;
end;


#6


自己顶

#7


1:现在接受事件可以被触发了,但是在运行Install_IC函数以后才能触发接受事件。

在Install_IC中创建了TComm的一个实例Comm_Temp1,所以只能在运行Install_IC函数后才能触发接收事件。

2: Comm_Temp1.free;不应该放在CommReceiveData中,除非你的程序只接收一次数据。我一般的做法是在用户关闭串口或是结束程序时释放端口;

3:为什么不把串口的开、关放在DLL中?