w-zero3日和

星羽がW-ZERO3、W-ZERO3[es]、その他モバイル端末を設定した時の覚え書きや自作アプリの公開など。

ver1.06までのPowerstatusPlusでアドエスでの表示に不具合が出た原因について

2007年08月04日 | 自作アプリ関連
予告したように、ver1.06までのPowerstarusPlusをアドエスで利用した場合にメモリバーの表示に不具合が出ていた原因についてご説明致します。

◆不具合の現象確認と原因の切り分け◆
不具合の現象としては、ver1.06をアドエスで利用すると、このようにメモリバーが異様に少なく表示されてしまうというものでした。

最初は「WindowsMobile6」なのが原因かと思ったのですが、バッテリー状態の表示に問題は無く、また、PowerstatusPlusのバーをタップした時に表示されるメモリ状態では、正常な数値を示していたので、「これはアプリ側のバグ」と考え直しました。

◆原因の追究◆
esとアドエスとの大きな違いは、「アドエスはメモリが倍になっている」ということですよね。
そこでプログラムを見直したところ、原因が判明しました!

プログラム実行用メモリ容量については、以下のように取得しています。
DWORD ex,cx 幅取得用変数
MEMORYSTATUS ms; メモリ状態取得用構造体定義
GlobalMemoryStatus(&ms); メモリ状態取得関数→結果はms構造体に
xWidth = GetSystemMetrics(SM_CXSCREEN); 画面の横幅取得
cx = xWidth / 2; 画面の横幅の半分を取得
ex = ex = cx*ms.dwAvailPhys/ms.dwTotalPhys; メモリ状態バー表示幅計算

ms.dwTotalPhys:プログラム実行用メモリの合計
ms.dwAvailPhys:プログラム実行用メモリの残量

ここで赤字で書いた部分が根本的な不具合の原因になっていました。
この計算は、「cxがms.dwTotalPhysなら、ms.dwAvailPhysの場合は?」という考えから出てきた以下の比例計算を変形したものです。

cx:ms.dwTotalPhys = ex:ms.dwAvailPhys
ex/cx = ms.dwAvailPhys/ms.dwTotalPhys
ex = cx*ms.dwAvailPhys/ms.dwTotalPhys

アプリを作ってるとたまにこういう数学が役に立つことがあるんですよね☆
全然関係ないですけど、アクションゲームとかを作る場合はほとんどが物理計算で動きを計算するので、アクションゲームを作りたいと考えている学生の方は、物理を真面目に勉強しておくと役に立ちますよ。
学生でない方は物理の教科書を買って眺めてるとゲーム作りのヒントが得られるかも?

それはいいとして、何故この計算が不具合の原因だったのかというと、exがDWORD型として定義されているからです。
DWORD(Double Word) = Word型が2つ = Word型は2byteなので4byte = 4byteで表せるのはFFFFFFFF(4,294,967,295)まで。

でms.dwAvailPhysもms.dwTotalPhysもbyteで数値が格納されているため、それにcx(通常の場合、320/2=160ですね)を掛けた結果がDWORDで表せる数値を超えてしまったため、値がちょん切れて取得されていたせいで、メモリバーの表示に不具合が出ていたのでした。

◆解決策◆
そこで、計算式を以下のように変更しました。
ex = cx*((float)ms.dwAvailPhys/(1024*1024))/((float)ms.dwTotalPhys/(1024*1024));
(1024*1024)で割ることでbyte→MBへ先に変換しちゃってます。
これで数値がかなり小さくなり、結果も正常に取得出来るようになりました。
(float)を付けているのは、byte→MBに変換した時に結果を小数点まで持たせた方が、より正確な数値を示せるからです。(通常割り算の結果は整数になってしまうので)

簡単な計算式の変更で不具合が解決出来て良かったです☆


最新の画像もっと見る