Function GetGBCord:PChar;StdCall;S:=String(PChar(Funct));可能是GetGBCord这个函数返回的地址已失效.
Function GetIniFileParam(IniFileName,IniField,KeyWord:String):String; Var F:Tinifile; Begin F:=TiniFile.Create(IniFileName); GetIniFileParam:=F.ReadString(IniField,KeyWord,''); F.Destroy; End;Function StrAllNum(S:String):Byte; Const K=['0'..'9']; Var P,X:Integer; N:String; Begin P:=0; StrAllNum:=10; If S='' Then Exit; For X:=1 To Length(S) Do If(S[X] In K)=False Then P:=10; If P>0 Then Begin N:=S; P:=1; If N[1]='-' Then Delete(N,1,1); If Pos('.',N)>0 Then Delete(N,Pos('.',N),1); If N='' Then P:=10 Else For X:=1 To Length(N) Do If (N[X] In K)=False Then P:=10; End; StrAllNum:=P; End;Function GetGBCord:PChar; Const AAA='69412345';//这个是函数原型 Const GB:Array[1..2]Of String=('[GB_CORD]','国标码='+AAA); Const FGFile='AAAA.INI'; Var Fn,S:String; F:TextFile; Begin S:=AAA; Fn:=LocalDir+'SYSTEM\'+FGFile; If FileExists(Fn)=False Then Begin AssignFile(F,Fn); ReWrite(F); Writeln(F,GB[1]); Writeln(F,GB[2]); CloseFile(F); End Else Begin Fn:=GetIniFileParam(Fn,'GB_CORD','国标码'); // 上面有定义 If Fn<>'' Then If Length(Fn)=Length(AAA)Then If StrAllNum(Fn)=0 Then S:=Fn;//StrAllNum上面有定义 End; GetGBCord:=PChar(S); End;
改一下GetGBCord: procedure GetGBCord(var GBCord: string); Const AAA='69412345';//这个是函数原型 Const GB:Array[1..2]Of String=('[GB_CORD]','国标码='+AAA); Const FGFile='AAAA.INI'; Var Fn,S:String; F:TextFile; Begin S:=AAA; Fn:=LocalDir+'SYSTEM\'+FGFile; If FileExists(Fn)=False Then Begin AssignFile(F,Fn); ReWrite(F); Writeln(F,GB[1]); Writeln(F,GB[2]); CloseFile(F); End Else Begin Fn:=GetIniFileParam(Fn,'GB_CORD','国标码'); // 上面有定义 If Fn <>'' Then If Length(Fn)=Length(AAA)Then If StrAllNum(Fn)=0 Then S:=Fn;//StrAllNum上面有定义 End; GBCord:=s; //GetGBCord:=PChar(S); End;
Function GetGBCord:PChar;StdCall; 返回的是一个Char指针,那么指针指向的内存是由Dll申请的,所以因由dll释放。改成如下Function GetGBCord(PChar outResult): bool;StdCall;调用的时候是这样var outResult: String; //这里如果用PChar的话,就要Getmem 和Freemem来申请和释放内存 begin SetLength(outResult,100); //这个长度应为GetGBCord可能返回结果的最大值 GetGBCord(@outResult[1]); end;楼主在试一下吧
这句语法好像看不懂
错误应该是使用已经释放的对象造成的
type
Test = Function:PChar;StdCall;
var
Funct: Test;
一样的
掉用DLL要遵循一个原则,谁创建谁释放,建议楼主修改一下接口
Var F:Tinifile;
Begin
F:=TiniFile.Create(IniFileName);
GetIniFileParam:=F.ReadString(IniField,KeyWord,'');
F.Destroy;
End;Function StrAllNum(S:String):Byte;
Const K=['0'..'9']; Var P,X:Integer; N:String;
Begin
P:=0;
StrAllNum:=10;
If S='' Then Exit;
For X:=1 To Length(S) Do If(S[X] In K)=False Then P:=10;
If P>0 Then
Begin
N:=S;
P:=1;
If N[1]='-' Then Delete(N,1,1);
If Pos('.',N)>0 Then Delete(N,Pos('.',N),1);
If N='' Then P:=10 Else
For X:=1 To Length(N) Do If (N[X] In K)=False Then P:=10;
End;
StrAllNum:=P;
End;Function GetGBCord:PChar; Const AAA='69412345';//这个是函数原型
Const GB:Array[1..2]Of String=('[GB_CORD]','国标码='+AAA);
Const FGFile='AAAA.INI'; Var Fn,S:String; F:TextFile;
Begin
S:=AAA;
Fn:=LocalDir+'SYSTEM\'+FGFile;
If FileExists(Fn)=False Then
Begin
AssignFile(F,Fn);
ReWrite(F);
Writeln(F,GB[1]);
Writeln(F,GB[2]);
CloseFile(F);
End Else
Begin
Fn:=GetIniFileParam(Fn,'GB_CORD','国标码'); // 上面有定义
If Fn<>'' Then If Length(Fn)=Length(AAA)Then
If StrAllNum(Fn)=0 Then S:=Fn;//StrAllNum上面有定义
End;
GetGBCord:=PChar(S);
End;
procedure GetGBCord(var GBCord: string); Const AAA='69412345';//这个是函数原型
Const GB:Array[1..2]Of String=('[GB_CORD]','国标码='+AAA);
Const FGFile='AAAA.INI'; Var Fn,S:String; F:TextFile;
Begin
S:=AAA;
Fn:=LocalDir+'SYSTEM\'+FGFile;
If FileExists(Fn)=False Then
Begin
AssignFile(F,Fn);
ReWrite(F);
Writeln(F,GB[1]);
Writeln(F,GB[2]);
CloseFile(F);
End Else
Begin
Fn:=GetIniFileParam(Fn,'GB_CORD','国标码'); // 上面有定义
If Fn <>'' Then If Length(Fn)=Length(AAA)Then
If StrAllNum(Fn)=0 Then S:=Fn;//StrAllNum上面有定义
End;
GBCord:=s;
//GetGBCord:=PChar(S);
End;
outResult: String; //这里如果用PChar的话,就要Getmem 和Freemem来申请和释放内存
begin
SetLength(outResult,100); //这个长度应为GetGBCord可能返回结果的最大值
GetGBCord(@outResult[1]);
end;楼主在试一下吧