Hi,
I encounter strange thing. Look at this program please:
var
LibraryHandle: TLibHandle;
cw: word;
begin
cw:=Get8087CW;
writeln('CW before:',cw, ' IntPower:', intpower(10,-6));
LibraryHandle:=LoadLibrary('odbc32.dll');
writeln('CW after:',Get8087CW, ' IntPower:', intpower(10,-6));
Set8087CW(cw);
end.
Output:
CW before:4978 IntPower: 1.0000000000000000E-0006
CW after:4722 IntPower: 2.0000000000000000E-0006 <--- Wrong result
of IntPower!!!
As you can see, LoadLibrary changes FPU control word (from $1372 to
$1272, from 64bit precision to 53bit precision).
Which leads to wrong result of PowerInt.
But it seems, that this happens on *Windows98* only, on Windows XP,Vista
it does not happen.
Do you have same experience on Windows98?
If yes, then I think, that good idea will be use SafeLoadLibrary instead
of LoadLibrary (which partialy solves this problem).
Next:
But this error I have encounter when running fcl-db tests suite with
IBConnection, where is PowerInt used.
When I change in "ibase60.inc" LoadLibrary to SafeLoadLibrary problem
still exists, because later call to "isc_attach_database" again changes
FPU control word. So I must save CW before call to "isc_attach_database"
and then reset CW to original value.
This solves problem.
Please look at attached patches . Do you think, that this approach is
acceptable or is there any other solution ?
BTW:
When I look at function SafeLoadLibrary in dynlibs.pas there is used :
{$ifdef i386}
w:=get8087cw;
When I look at function SafeLoadLibrary in SysUtils.inc there is used :
{$if defined(cpui386) or defined(cpux86_64)}
fpucw:=Get8087CW;
Which conditional is correct ? ("i386" or "cpui386")
Looking at
http://www.freepascal.org/docs-html/prog/progap7.html#x316-331000G ... I
see no "i386" ?
And what "FPUX87" ? Can not be used this ?
Thanks
-Laco.
--- ibase60.inc.ori Sat Feb 19 19:24:38 2011
+++ ibase60.inc Wed Aug 17 08:59:28 2011
@@ -2458,7 +2458,7 @@ begin
Result := 0;
if (RefCount=0) then
begin
- IBaseLibraryHandle:=LoadLibrary(LibraryName);
+ IBaseLibraryHandle:=SafeLoadLibrary(LibraryName);
if (IBaseLibraryHandle=nilhandle) then
Exit;
inc(RefCount);
--- ibconnection.pp.ori Tue Aug 09 14:18:46 2011
+++ ibconnection.pp Wed Aug 17 09:23:14 2011
@@ -381,6 +381,9 @@ procedure TIBConnection.ConnectFB;
var
ADatabaseName: String;
DPB: string;
+{$if defined(cpui386) or defined(cpux86_64)}
+ cw: word;
+{$endif}
begin
DPB := chr(isc_dpb_version1);
if (UserName <> '') then
@@ -397,10 +400,16 @@ begin
FSQLDatabaseHandle := nil;
if HostName <> '' then ADatabaseName := HostName+':'+DatabaseName
else ADatabaseName := DatabaseName;
+{$if defined(cpui386) or defined(cpux86_64)}
+ cw:=get8087cw;
+{$endif}
if isc_attach_database(@FStatus[0], Length(ADatabaseName), @ADatabaseName[1],
@FSQLDatabaseHandle,
Length(DPB), @DPB[1]) <> 0 then
CheckError('DoInternalConnect', FStatus);
+{$if defined(cpui386) or defined(cpux86_64)}
+ set8087cw(cw);
+{$endif}
end;
function TIBConnection.GetDialect: integer;
_______________________________________________
fpc-devel maillist - fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel