大侠们给看看:
TfrmA = class(TfrmB)
btnSet: TBitBtn;
private
I: Integer;
public
procedure Test;
end;procedure TfrmATest;
var
Handle1, Handle2: THandle;
begin
XHandle := Self.Hanlde;
I := 1;
if I = 1 then
GetX() //GetX为动态库函数
Handle2 := Self.Handle;
else
....; 调用之后:
此时 I 已经不为1了,而是一个很大的负数
Handle1与Handle也不相等,为什么?
end;
TfrmA = class(TfrmB)
btnSet: TBitBtn;
private
I: Integer;
public
procedure Test;
end;procedure TfrmATest;
var
Handle1, Handle2: THandle;
begin
XHandle := Self.Hanlde;
I := 1;
if I = 1 then
GetX() //GetX为动态库函数
Handle2 := Self.Handle;
else
....; 调用之后:
此时 I 已经不为1了,而是一个很大的负数
Handle1与Handle也不相等,为什么?
end;
看起来像是堆栈中的Self指针被破坏了
TAnalyseGetData = function(sParam:pchar;iParamLen:integer;sDataFormat:pchar;sBack:pchar): integer;stdcall;function AnalyseGetData(sParam:pchar;iParamLen:integer;sDataFormat:pchar): ReturnChar ;
var
iBack:integer;
th:Thandle;
anaData:TAnalyseGetData;
tp:TFarProc;
reChar:ReturnChar;
i : integer;
sBack : pchar;
begin
iBack := 0;
th := LoadLibrary('.\645_1997.dll');
if (th > 0) then
begin
try
tp := GetProcAddress(th,'AnalyseGetData');
if (tp <> nil) then
begin
anaData := TAnalyseGetData(tp);
getMem(sBack,sizeof(pchar));
iBack := anaData(sParam,iParamLen,sDataFormat,@sBack);
reChar.iLen := iBack;
if iBack > 0 then
for i := 0 to iBack -1 do
reChar.sBack := reChar.sBack + sBack[i];
//FreeMem(@sBack);
end //if (tp <> nil) then
else
begin
iback := 0;
reChar.iLen := iBack;
reChar.sBack := '';
end;
finally
FreeLibrary(th);
end;//try
end;//if (th > 0) then
result := reChar;
end;
调用:
rec := AnalyseGetData(pchar(sBuffer),
4,
pchar(node.strings[6]));
2、两个sBack,编译能通过?
3、getMem(sBack,sizeof(pchar));字符串只要四个字节就够了?
4、645_1997.dll中AnalyseGetData方法的实现或者调用规范是什么?
5、for i := 0 to iBack -1 do reChar.sBack := reChar.sBack + sBack[i];用不着这么写
6、代码你可以重写了
记录类型
type
ReturnChar = record
iLen : integer;
sBack: string;
end;
2、两个sBack,编译能通过?
没看到两个,编译无问题。 若你是指reChar.sBack := reChar.sBack + sBack[i]; 请看问题13、getMem(sBack,sizeof(pchar));字符串只要四个字节就够了?
此处似乎有待斟酌,我再仔细看看4、645_1997.dll中AnalyseGetData方法的实现或者调用规范是什么?
无源码,
C++声明为:
函数定义 int AnalyseGetData(char *sParam,int iParamLen,char *sDataFormat,char *&sBack )
函数用途 解析查询返回的报文
参数 sParam:[输入量],查询返回的报文
iParamLen:[输入量],报文长度
sDataForamt:[输入量],数据格式
sBack:[输出量],输出解析报文
返回值 int,解析后的报文长度5、for i := 0 to iBack -1 do reChar.sBack := reChar.sBack + sBack[i];用不着这么写
直接这么写?reChar.sBack := sBack6、代码你可以重写了
别人都用了很长时间了,最后考虑。
int AnalyseGetData(char *sParam,int iParamLen,char *sDataFormat,char *&sBack)
最后一个参数是返回一个char *,而不是传入一个char *让AnalyseGetData为其填充字符串
因此对应的调用规范应该是
function AnalyseGetData(sParam:pchar;iParamLen:integer;sDataFormat:pchar;var sBack:pchar): integer;stdcall;
因此你只要申明一个PChar指针就可以了,AnalyseGetData会为字符串开辟一段内存,并写好数据,然后把地址写到你这个PChar指针中去,因此字符串数据是无法释放的,会导致内存泄露
TAnalyseGetData = function(sParam:pchar;iParamLen:integer;sDataFormat:pchar;var sBack:pchar): integer;stdcall; function AnalyseGetData(sParam:pchar;iParamLen:integer;sDataFormat:pchar): ReturnChar ;
var
iBack:integer;
th:Thandle;
anaData:TAnalyseGetData;
tp:TFarProc;
reChar:ReturnChar;
i : integer;
sBack : pchar;
begin
iBack := 0;
th := LoadLibrary('.\645_1997.dll');
if (th > 0) then
begin
try
tp := GetProcAddress(th,'AnalyseGetData');
if (tp <> nil) then
begin
anaData := TAnalyseGetData(tp);
//getMem(sBack,sizeof(pchar)); 去掉分配内存
iBack := anaData(sParam,iParamLen,sDataFormat,sBack);
reChar.iLen := iBack;
if iBack > 0 then
reChar.sBack := sBack; //直接赋值
end //if (tp <> nil) then
else
begin
iback := 0;
reChar.iLen := iBack;
reChar.sBack := '';
end;
finally
FreeLibrary(th);
end;//try
end;//if (th > 0) then
result := reChar;
end;
调用:
rec := AnalyseGetData(pchar(sBuffer),
4,
pchar(node.strings[6]));
PS:LoadLibrary中用相对路径不保险;貌似ReturnChar中的iLen是多于的,string中第一个字节就是它的长度