本ページは公開が終了した情報の複製であり、掲載時点での情報です。本ページに記載されている内容について各所に問い合わせることはご遠慮下さい。
サポート技術情報

[MSVC]PC98用 Windows3.1(初期版)で発生する問題

文書番号: 402708

最終更新日: 1999/03/19


この資料は以下の製品について記述したものです。


この記事は、以前は次の ID で公開されていました: JP402708

概要

この資料は、NEC PC-98 シリーズ用 Microsoft(R) Windows(R) Version 3.1(初期版) (以下 Windows 3.1) で発生する問題について説明したものです。
Windows 3.1 は、Microsoft 製、NEC 製、EPSON 製 いずれも該当します。

詳細

数値演算プロセッサ搭載のパソコンで NEC PC-98 シリーズ用 Windows 3.1 (初期版) 上で、以下の3条件をすべて満たす EXE を起動し終了した後、数値演算を行うア
プリケーション (Microsoft Excel など) を起動すると、Windows 3.1 がハング
アップすることがあります。
  条件1: EXE そのものは、数値演算ライブラリをリンクしていない。
  条件2:数値演算ライブラリをリンクしている DLL を利用している。
  条件3: DLL は LoadLibrary, FreeLibrary API 関数を用いて呼び出している。
数値演算ライブラリは、特別な演算を行わなくても、浮動小数点型の四則演算を行うと リンクされます。
Windows 3.1 起動直後には確実に再現しますが、他のアプリケーションを使用した
後では、発生しにくくなります。数値演算を行うアプリケーション起動中には、
発生しません。

原因

PC-98 シリーズ用 Windows 3.1 (初期版) の障害です。

対処方法

DLL に後述のコードを追加することで、回避できます。
Windows 3.1 自体は、アップデートモジュールにより改修できます。アップデートされ ている環境ではこの現象は起こりませんが、開発した DLL を頒布する場合などは DLL 側の対応をお勧めします。この修正を施した DLL は、アップデートされた環境や
PC-98 シリーズ用 以外の Windows 3.1 上でも正常に動作します。
DLL 終了時に呼び出される WEP 関数は、ランタイムライブラリの中で定義されてお
り、ここからユーザ WEP 関数である _WEP 関数を呼び出しています。_WEP 関数
を以下のように定義してください。
  DLL を C で作成する場合                 DLL を C++ で作成する場合
  -----------------------                 -------------------------
  #pragma oputimize( "", off )            #pragma oputimize( "", off )
  extern void _fpmath();                  extern "C" void _fpmath(void);
  int CALLBACK _WEP(int)                  extern "C" int CALLBACK _WEP( int )
  {                                       {
    _asm{                                     _asm{
      mov   bx, 2                             mov   bx, 2
      call  _fpmath                           call  _fpmath
    }                                       }
    return TRUE;                            return TRUE;
  }                                       }
  #pragma oputimize( "", on )             #pragma oputimize( "", on )
MFC を使用して DLL を作成する場合は、_WEP 関数は MFC 内部で定義済みですので、 ユーザが定義して使用することはできません。MFC が定義している_WEP 関数が呼び
出している CWinApp::ExitInstance メンバ関数は仮想(virtual) 関数なので、これ
をユーザ定義のアプリケーションクラスでオーバーライドし、以下のように定義
してください。

DLL を MFC で作成する場合

  #pragma oputimize( "", off )
  extern "C" void _fpmath();
  int CUserApp::ExitInstance()
  {
    _asm{
      mov   bx, 2
      call  _fpmath
    }
    return CWinApp::ExitInstance();
  }
  #pragma oputimize( "", on )

注意

CUserApp クラスは、ユーザ定義のアプリケーションクラス名を示します。
Small,Compact メモリモデルで使用する場合、_fpmath のプロトタイプ宣言に __far キーワードを指定してください。

詳細

  • Visual C++ は、米国 Microsoft Corporation の商標です。

Keywords: C7 KBBUG VC10 VC15 KB402708
Technology: kbAudDeveloper kbvc150 kbVCsearch kbZNotKeyword3 kbZNotKeyword8

inserted by FC2 system