基本的に次の 3 つのことを行うアプリケーションがあります。
- ユーザーに画像を表示する
- ユーザーに 1 ~ 2 秒のサウンド (wav) を再生します。
- マイク入力を 4 秒間録音します (サウンドの再生中)。
これはユーザーごとに 280 回発生し、すべての記録は各ユーザーのディレクトリに保存されます。ただし、プログラムの最後の 18 回の実行のうち 2 回は、モジュール ntdll.dll のコード c0000005 (アクセス違反として説明されています) の未処理の例外からクラッシュしました。私が使用している唯一のアンマネージ API 呼び出しは、winmm.dll からの mciSendString で、wav ファイルの長さを取得して録音を行います。再生は、WindowsMediaPlayer のインスタンスを使用して行われます。
クラッシュはランダムなようで、両方とも同じマシンで発生しました (3 つが使用されています)。これらは私の質問です: ntdll.dll は本当に例外の原因ですか? アクセス違反が無効なメモリ アクセスであることを理解しているのは正しいですか? .NET 仮想マシンで実行されている C# プログラムでは、どのようにしてそれが起こるのでしょうか?
リクエストにより、mciSendString を呼び出すクラスの 1 つを次に示します。
public class JE_SR
{
[DllImport("winmm.dll", EntryPoint = "mciSendStringA",
CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
private static extern uint mciSendString(string lpstrCommand,
string lpstrReturnString, int uReturnLength, int hwndCallback);
[DllImport("winmm.dll", CharSet = CharSet.Auto)]
private static extern int mciGetErrorString(uint errorCode,
StringBuilder errorText, int errorTextSize);
private static bool recording = false;
public static uint lastResult;
public static void startRecording()
{
if (recording)
{
return;
}
tryMCISendString("open new Type waveaudio Alias recsound", "", 0, 0);
tryMCISendString("record recsound", "", 0, 0);
recording = true;
}
public static void stopRecording(string file)
{
if (!recording)
{
return;
}
if (!file.Equals(""))
{
tryMCISendString("save recsound " + file, "", 0, 0);
tryMCISendString("close recsound ", "", 0, 0);
}
else
{
tryMCISendString("close all", "", 0, 0);
}
recording = false;
}
public static void tryMCISendString(string lpstrCommand,
string lpstrReturnString, int uReturnLength, int hwndCallback)
{
lastResult = mciSendString(lpstrCommand, lpstrReturnString, uReturnLength, hwndCallback);
StringBuilder error = new StringBuilder(256);
if(lastResult != 0)
{
mciGetErrorString(lastResult, error, error.Length);
JE_Log.logMessage("MCIERROR(JE_SR): " + error.ToString());
}
}
}
他に含める必要がある関連する詳細があれば教えてください...