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

Reply via email to