用OPC Client开发时,需要从如下几个地方注意内存泄露:
(1)所有返回的指针,都要用CoTaskMemFree释放,如:
[delphi] view plaincopy
function Group_TryAddItems(AGroupIntf:IOPCItemMgt;AItemCount:integer;AItems:POPCITEMDEFARRAY):POPCITEMRESULTARRAY;
var
vErrors: PResultList;
begin
Result:=nil;
vErrors:=nil;
if AGroupIntf.AddItems(AItemCount,PSafeArray(AItems),Result,vErrors)<>S_OK then
begin
CoTaskMemFree(Result);
Result:=nil;
end;
CoTaskMemFree(vErrors);
end;
(2)用ISyncRead接口读取资料后,要用VariantClear释放,如:
[delphi] view plaincopy
function Group_ReadItem2(AGroupIntf:IOPCItemMgt;AItemServerHandle:OPCHandle;out AQuality:Word):OLEVariant;
var
vErrors:PResultList;
vOPCSyncIO:IOPCSyncIO;
ItemValues: POPCITEMSTATEARRAY;
begin
OLECheck(AGroupIntf.QueryInterface(IID_IOPCSyncIO,vOPCSyncIO));
try
OPCErrorCheck(vOPCSyncIO.Read(OPC_DS_DEVICE,1,@AItemServerHandle,ItemValues,vErrors));
try
OPCResultErrorsCheck(1,nil,null,vErrors);
Result:=ItemValues^[0].vDataValue;
AQuality:=ItemValues^[0].wQuality;
finally
VariantClear(ItemValues^[0].vDataValue); //memory leak
CoTaskMemFree(ItemValues);
end;
finally
vOPCSyncIO:=nil;
end;
end;
(1)所有返回的指针,都要用CoTaskMemFree释放,如:
[delphi] view plaincopy
function Group_TryAddItems(AGroupIntf:IOPCItemMgt;AItemCount:integer;AItems:POPCITEMDEFARRAY):POPCITEMRESULTARRAY;
var
vErrors: PResultList;
begin
Result:=nil;
vErrors:=nil;
if AGroupIntf.AddItems(AItemCount,PSafeArray(AItems),Result,vErrors)<>S_OK then
begin
CoTaskMemFree(Result);
Result:=nil;
end;
CoTaskMemFree(vErrors);
end;
(2)用ISyncRead接口读取资料后,要用VariantClear释放,如:
[delphi] view plaincopy
function Group_ReadItem2(AGroupIntf:IOPCItemMgt;AItemServerHandle:OPCHandle;out AQuality:Word):OLEVariant;
var
vErrors:PResultList;
vOPCSyncIO:IOPCSyncIO;
ItemValues: POPCITEMSTATEARRAY;
begin
OLECheck(AGroupIntf.QueryInterface(IID_IOPCSyncIO,vOPCSyncIO));
try
OPCErrorCheck(vOPCSyncIO.Read(OPC_DS_DEVICE,1,@AItemServerHandle,ItemValues,vErrors));
try
OPCResultErrorsCheck(1,nil,null,vErrors);
Result:=ItemValues^[0].vDataValue;
AQuality:=ItemValues^[0].wQuality;
finally
VariantClear(ItemValues^[0].vDataValue); //memory leak
CoTaskMemFree(ItemValues);
end;
finally
vOPCSyncIO:=nil;
end;
end;