=====PChar内存释放问题,大侠帮忙=====
症状:在IDE环境下直接运行或单步执行数据正确,直接运行可执行文件数据不正确
正确数据:68 03 00 00 00 00 00 68 04 09 44 F3 33 33 33 33 55 55 55 E2 16
错误数据:68 03 00 00 00 00 00 68 04 09 44 F3 33 33 33 33 93 93 93 9C 16
初步诊断内存分配、释放问题,在集成环境下有内存保护机制所以没有报错,但不能确认到底问题出在哪处!!
另外,一直玩不转PChar这个类型,如果哪位对此理解深刻望能给指点一二,尤其在作为参数在DLL与调用程序之间传递返回数据的使用,包括,在哪分配,在哪释放。请高人指点。
目前的权限只能给200分,以后再补吧。
程序代码如下(虽多莫怕,按照我写的次序很快就明白了):
用到的一个记录类型
type
ReturnChar = record
iLen : integer;
sBack: string;
end;
----------------------
发送数据
procedure TfrmBaseSet.SetData(node: TdxTreeListNode);
var
i: integer;
sSetData: string;
reBack: ReturnChar;
sDisp: string;
begin
if node <> nil then
begin
i := strToInt('$'+node.Values[4]);
sSetData := node.Values[2] + '00000000';
reback := SetParam(pchar(sAddr), i, PChar(sSetData)); //调用函数往下看
for i := 1 to length(reback.sBack) do
sDisp := sDisp + format('%.2x',[ord(reback.sBack[i])]) + ' '; 截获的显示数据
ShowMessage(sDisp);
end;
--------------------------------
function SetParam(sAddr:pchar; iParamNo:integer; sData:pchar) : ReturnChar ;
var
iBack:integer;
th:Thandle;
theSetParam:TSetParam; 声明原型在下边
tp:TFarProc;
reback:ReturnChar;
i : integer;
sBack : pchar;
begin
iBack := 0;
th := LoadLibrary('.\645_1997.dll');
if (th > 0) then
begin
try
tp := GetProcAddress(th,'SetParam');
if (tp <> nil) then
begin
theSetParam := TSetParam(tp);
//getMem(sBack,sizeof(pchar));
iBack := theSetParam(sAddr,iParamNo, sData, length(sData) div 2, @sBack); //动态库函数
reback.iLen := iBack;
for i := 0 to iBack -1 do
reBack.sBack := reBack.sBack + sBack[i];
//FreeMem(sBack); //sBack是在DLL是分配的内存,我在此释放报错!
end //if (tp <> nil) then
else
begin
iback := 0;
reBack.iLen := iBack;
reBack.sBack := '';
end;
finally
FreeLibrary(th);
end;//try
end;//if (th > 0) then
result := reBack;
end;
----------------------------------------
TSetParam = function(sAddr:pchar;iParamNo:integer;sData:pchar;iDataLen:integer;sBack:pchar) : integer;cdecl;
//-----------------------------VC写的动态库函数--------------------------------------------
//参数:sAddr:表地址;iParamNo:功能码;sData:设定值;iDataLen:数据长度;sBack:返回报文
//
int CMy645_1997App::SetParam(char *sAddr,int iParamNo,char *sData,int iDataLen,char *&sBack)
{
int iLen;//报文长度
// BYTE check;//校验码
char* sFun;
iLen = 15 + iDataLen;
sBack = new char[iLen];
sBack[0] = 0x68;
//写入地址码
char *s = GetFormatAddr(sAddr);
for (int i = 0;i<6;i++)
{
sBack[i+1] = s[i];
}
sBack[7] = 0x68;
sBack[8] = 0x04;//04写数据
sBack[9] = 0x02+iDataLen;
sBack[10] = (iParamNo & 0xFF) + 0x33;
sBack[11] = ((iParamNo >> 8) & 0xFF) + 0x33;
sFun = new char[3];
for (int i = 0;i<iDataLen;i++)
{
sFun[0] = sData[iDataLen*2-i*2-2];
sFun[1] = sData[iDataLen*2-i*2-1];
sBack[12 + i] = hex_2bcd(atoi(sFun)) + 0x33;
}
sBack[12 + iDataLen] = GetCheck(sBack,12+iDataLen);
sBack[13 + iDataLen] = 0x16;
delete [] s;
delete [] sFun;
return iLen-1;
}