L
Lynn McGuire
Okay. My mistake.
There is a difference(!) when calling InitTestDLL from XL2003 VBA v. XL2010 VBA. And I misinterpreted the results from XL2003 VBA.
When InitTestDLL is called from XL2003 VBA, the last MsgBox displayed by checkMathCoprocessorStatus says "was 0x127f" and "is now
0x127f" the first time.
But subsequent times, it says "was 0x137f" and "is now 0x137f".
That led me to conclude that your DLL is changing the FPU control word in some way completely unrelated to the code we see in your
testdll.c.
But when InitTestDLL is called from XL2010 VBA, we see "was 0x137f" and "is now 0x137f" for the first call and for all subsequent calls.
That is consistent with the code in your testdll.c
Ergo, the change that I see with XL2003 VBA is probably due to VBA, not your code.
(Although I had used XL2003 for my initial test of your code, I had switched to XL2010 unconsciously for my subsequent testing. Mea
culpa!)
Based on Martin's assumption that your version of _control87 is displaying the actual FPU control word, 0x127f corresponds to _PC_53
+ _RC_NEAR, and 0x137f corresponds to _PC_64 + _RC_NEAR.
That would indeed explain the results that we observe with your testdll.dll, namely: chptst is zero the first time, but about
2.85E-10 subsequent times when using XL2003.
But when using XL2010, you see about 2.85E-10 consistently.
As Martin and I have said repeatedly, the remedy is for you to call _control87(_PC53 + _RC_NEAR, _MCW_PC + _MCW_RC) at the
__beginning__ of InitTestDLL.
(Technically, _RC_NEAR and _MCW_RC are not needed since it appears that _RC_NEAR is already set. But it is good "defensive
programming" to set both modes.)
Alternatively, as I explained previously, you can call a DLL routine directly from the VBA procedure CommandButton1_Click. The DLL
routine would call _control87(_PC53 + _RCNEAR, _MCW_PC + _MCW_RC).
That would obviate the need to call _control87 from each DLL routine that you might call from CommandButton1_Click.
But you would need to call that DLL routine from every VBA procedure that you initiate, either with an Excel "button" or by calling a
VBA function from an Excel formula.
So arguably, it is more reliable to call _control87 (or a DLL routine) from each entry point that allow to be called from VBA.
Done. No better calcs.
The Math Coprocessor status is 0x4020 and control is 0x137f
The Math Coprocessor status is is now 0x127f
The Math Coprocessor status is 0x4000 and control is 0x127f
The Math Coprocessor status is is now 0x127f
The Math Coprocessor status is 0x4000 and control is 0x127f
The Math Coprocessor status is is now 0x127f
I call the following code from each entry point.
unsigned checkMathCoprocessorStatus ()
{
unsigned old87Status = 0;
unsigned old87Control = 0;
unsigned new87result = 0;
old87Status = _status87 ();
old87Control = _control87 (0, 0);
//if (old87Status != 0)
{
char msg [4096];
sprintf (msg, "\nThe Math Coprocessor status is 0x%x and control is 0x%x\n\n", old87Status, old87Control);
writeLineToScreen (msg);
// new87result = _control87 (_PC_64 + _RC_NEAR, _MCW_PC + _MCW_RC);
// new87result = _control87 (_PC_53, _MCW_PC);
// new87result = _control87 (_PC_64, _MCW_PC);
// new87result = _control87 (_RC_NEAR, _MCW_RC);
// _asm { FINIT };
//new87result = _control87 (0x27f, 0xffff);
//new87result = _control87 (0, 0);
new87result = _control87 (_PC_53 + _RC_NEAR, _MCW_PC + _MCW_RC);
sprintf (msg, "\nThe Math Coprocessor status is is now 0x%x\n\n", new87result);
writeLineToScreen (msg);
}
return old87Status;
}
Thanks,
Lynn