定义了一个通信动态库文件,定义4个接口供主台调用,主台现在做一个监控程序需要循环抄读数据,且不停的调用这个动态库接口InitComm,Sendframe,Closecomm,需要不停的创建和释放串口,在这个动态库中使用的是Delphi的第三方控件Spcomm,问题的是有时候循环几十次出问题,有时候循环几百次出问题,都报的是内存泄露那里的错,估计是哪里内存没释放掉,报错地方都是CloseComm接口中调用FreeAndnil这个函数,请高手赐教!
unit PC_P_Comm;interfaceUses
SpComm,Windows,Forms,SysUtils,Classes,Dialogs,ScktComp,XMLDoc,XMLIntf,
IdBaseComponent, IdComponent;
type
TBaseComm=Class(TObject) //The Base Comm;
private
procedure AnalyseCommParamXML(Str_XML:string);
function Check1107RecFrameEnd(Str_RecFrame:string):Integer;
function Check62056RecFrameEnd(Str_RecFrame:string):Integer;
procedure Delay(i_Msc:LongInt);
function GetErrorMsg(i_ErrorCode:Integer):string;
public
constructor Create();overload;
destructor Destroy();override;
function InitComm(Str_XML:string):Integer;virtual;abstract;
function SendFrame(Str_SendFrame:string;var Str_RecFrame:string):Integer;virtual;abstract;
function StopComm():Integer;virtual;abstract;
end; TLocalComm=Class(TBaseComm) //The Class of Port Comm;
private
Comm:TComm;
procedure CommReceiveData(Sender: TObject; Buffer: Pointer;BufferLength: Word);
public
constructor Create();overload;
destructor Destroy();override;
function InitComm(Str_XML:string):Integer;override;
function SendFrame(Str_SendFrame:string;var Str_RecFrame:string):Integer;override;
function StopComm():Integer;override;
end;
var
Gl_Str_CommTypeNo:string;
Gl_Cls_LocalComm:TLocalComm;
//供主台调用的四个接口
function InitComm(P_Str_XML,P_Str_Error:PChar):Integer;stdcall;
function SendFrame(P_Str_SendFrame,P_Str_RecFrame,P_Str_Error:PChar;i_NewBaudrate:Integer=0):Integer;stdcall;
function StopComm():Integer;stdcall;
function CloseComm():Integer;stdcall;implementation//Initial the Communication(External Interface)
function InitComm(P_Str_XML,P_Str_Error:PChar):Integer;stdcall;
var
Str_CommTypeNo:string;
begin
//创建对象
Gl_Cls_LocalComm:=TLocalComm.Create;
Result:=Gl_Cls_LocalComm.InitComm(Str_InXML);
if Result<0 then
begin
Str_Error:=Gl_Cls_LocalComm.GetErrorMsg(Result);
StrPCopy(P_Str_Error,Str_Error);
Exit;
end;
end
//Close the communication(External Interface)
function CloseComm():Integer;stdcall;
begin
Result:=0;
if not Assigned(Gl_Cls_LocalComm) then
begin
Result:=-1;
Exit;
end;
//报内存泄露错误处(释放内存出错)
FreeAndNil(Gl_Cls_LocalComm);
end;
//-------------------------------Base Comm Class--------------------------------
//Base Creation
constructor TBaseComm.Create();
begin
Inherited Create();
Gl_B_ReceivedEnd:=False;
Gl_B_CheckRecFrameEnd:=False;
end;
//Destroy base class
destructor TBaseComm.Destroy();
begin
Inherited Destroy();
end;
//------------------------------Local Communication-----------------------------
//initialization the communication
constructor TLocalComm.Create();
begin
Inherited Create();
Comm:=TComm.Create(nil);
Comm.OnReceiveData:=CommReceiveData;
Gl_B_CheckRecFrameEnd:=False;
end;
//destory and free the comm
destructor TLocalComm.Destroy();
begin
try
Comm.StopComm;
Comm.Free;
except
end;
Application.ProcessMessages;
Inherited Destroy;
end;
//initialization the comm's prameters
function TLocalComm.InitComm(Str_XML:string):Integer;
begin
Result:=0;
Comm.CommName:='//./'+Gl_Str_CommName;
Comm.BaudRate:=Gl_i_Baudrate;
Comm.ByteSize:=TEumn_ByteSize[Gl_i_ByteSizeIndex];
Comm.StopBits:=TEumn_StopBits[Gl_i_StopBitsIndex];
Comm.Parity:=TEumn_Parity[Gl_i_ParityIndex];
Comm.ReadIntervalTimeout:=Gl_i_ReadIntervalTimeout;
//Start
Comm.Inx_XonXoffFlow:=False;
Comm.Outx_XonXoffFlow:=False;
Comm.StopComm;
try
Comm.StartComm;
Sleep(100);
except
Result:=con_CommERCode_InitCommFailed;
Comm.StopComm;
Exit;
end;
end;
unit PC_P_Comm;interfaceUses
SpComm,Windows,Forms,SysUtils,Classes,Dialogs,ScktComp,XMLDoc,XMLIntf,
IdBaseComponent, IdComponent;
type
TBaseComm=Class(TObject) //The Base Comm;
private
procedure AnalyseCommParamXML(Str_XML:string);
function Check1107RecFrameEnd(Str_RecFrame:string):Integer;
function Check62056RecFrameEnd(Str_RecFrame:string):Integer;
procedure Delay(i_Msc:LongInt);
function GetErrorMsg(i_ErrorCode:Integer):string;
public
constructor Create();overload;
destructor Destroy();override;
function InitComm(Str_XML:string):Integer;virtual;abstract;
function SendFrame(Str_SendFrame:string;var Str_RecFrame:string):Integer;virtual;abstract;
function StopComm():Integer;virtual;abstract;
end; TLocalComm=Class(TBaseComm) //The Class of Port Comm;
private
Comm:TComm;
procedure CommReceiveData(Sender: TObject; Buffer: Pointer;BufferLength: Word);
public
constructor Create();overload;
destructor Destroy();override;
function InitComm(Str_XML:string):Integer;override;
function SendFrame(Str_SendFrame:string;var Str_RecFrame:string):Integer;override;
function StopComm():Integer;override;
end;
var
Gl_Str_CommTypeNo:string;
Gl_Cls_LocalComm:TLocalComm;
//供主台调用的四个接口
function InitComm(P_Str_XML,P_Str_Error:PChar):Integer;stdcall;
function SendFrame(P_Str_SendFrame,P_Str_RecFrame,P_Str_Error:PChar;i_NewBaudrate:Integer=0):Integer;stdcall;
function StopComm():Integer;stdcall;
function CloseComm():Integer;stdcall;implementation//Initial the Communication(External Interface)
function InitComm(P_Str_XML,P_Str_Error:PChar):Integer;stdcall;
var
Str_CommTypeNo:string;
begin
//创建对象
Gl_Cls_LocalComm:=TLocalComm.Create;
Result:=Gl_Cls_LocalComm.InitComm(Str_InXML);
if Result<0 then
begin
Str_Error:=Gl_Cls_LocalComm.GetErrorMsg(Result);
StrPCopy(P_Str_Error,Str_Error);
Exit;
end;
end
//Close the communication(External Interface)
function CloseComm():Integer;stdcall;
begin
Result:=0;
if not Assigned(Gl_Cls_LocalComm) then
begin
Result:=-1;
Exit;
end;
//报内存泄露错误处(释放内存出错)
FreeAndNil(Gl_Cls_LocalComm);
end;
//-------------------------------Base Comm Class--------------------------------
//Base Creation
constructor TBaseComm.Create();
begin
Inherited Create();
Gl_B_ReceivedEnd:=False;
Gl_B_CheckRecFrameEnd:=False;
end;
//Destroy base class
destructor TBaseComm.Destroy();
begin
Inherited Destroy();
end;
//------------------------------Local Communication-----------------------------
//initialization the communication
constructor TLocalComm.Create();
begin
Inherited Create();
Comm:=TComm.Create(nil);
Comm.OnReceiveData:=CommReceiveData;
Gl_B_CheckRecFrameEnd:=False;
end;
//destory and free the comm
destructor TLocalComm.Destroy();
begin
try
Comm.StopComm;
Comm.Free;
except
end;
Application.ProcessMessages;
Inherited Destroy;
end;
//initialization the comm's prameters
function TLocalComm.InitComm(Str_XML:string):Integer;
begin
Result:=0;
Comm.CommName:='//./'+Gl_Str_CommName;
Comm.BaudRate:=Gl_i_Baudrate;
Comm.ByteSize:=TEumn_ByteSize[Gl_i_ByteSizeIndex];
Comm.StopBits:=TEumn_StopBits[Gl_i_StopBitsIndex];
Comm.Parity:=TEumn_Parity[Gl_i_ParityIndex];
Comm.ReadIntervalTimeout:=Gl_i_ReadIntervalTimeout;
//Start
Comm.Inx_XonXoffFlow:=False;
Comm.Outx_XonXoffFlow:=False;
Comm.StopComm;
try
Comm.StartComm;
Sleep(100);
except
Result:=con_CommERCode_InitCommFailed;
Comm.StopComm;
Exit;
end;
end;
解决方案 »
- 如果要让自己的程序可以让SNMP统计
- VCL组件 + 设计模式 = ?
- 请问读ini文件的时候能不能通过值来找关键字?
- treeview中,要读取节点修改后的值应该如何做,谢谢!
- 有用过Dialogic语音开开发或东进DN1200语音卡开发的朋友吗?
- 救我
- 一个对于低手可能很难的关于 BinToHex() 使用的问题,不行的千万别逞能!!!! ^_^
- 请教:一个简单函数的使用---请举例代码说明
- 如何获得某窗体在屏幕的矩形坐标
- 庆祝专家分达100,请大家讨论加入WTO对中国的影响,请各自讨论对自己行业影响,up有分!
- Win7能安装delphi7吗
- 线程类中使用Txmldocument组件错误
只允许实例化一次.initialization
Gl_Cls_LocalComm:=TLocalComm.Create;finalization
if assigned(Gl_Cls_LocalComm) then FreeAndNil(Gl_Cls_LocalComm);