none
C#で作っている自作コンパイラに、曲を再生、停止する命令を実装したいです。しかし曲を停止命令を使うと、「保護されているメモリに読み取りまたは書き込み操作を行おうとしました。他のメモリが壊れていることが考えられます。」というエラーが出ます。 RRS feed

  • 質問



  • VISUAL C# 2010でコンパイラを作っています
    SOUNDPLAY (ファイル名)で曲を再生し、SOUNDSTOP (ファイル名)で同名の曲を停止するようにしたいです

    プログラムは、
    public MUSIC_Instruction(string name)
    {
    StringStream st = new StringStream(name);
    st.Jump(5);
    ~略~

    }

    で構文解析した後、同じクラスで

     ~略~

    private static MainMDXS2 mdxs = new MainMDXS2();

    public override void DoInstruction(ExpressionMediator exm, InstructionLine func, ProcessState state)
    {

    string str = null;
    str = ((ExpressionArgument)func.Argument).Term.GetStrValue(exm);
    string fileName = Program.MusicDir + str;


    //SOUND再生
    if (isSe == false)
    {
    if (isSet == true)
    {
    Uri u1 = new Uri(Program.ExeDir);
    Uri u2 = new Uri(u1, fileName);

    string uri = u1.MakeRelativeUri(u2).ToString();←ファイルの相対パス

    mdxs.SetSound2(uri);
    }
    if (isClose == true)
    {
    mdxs.CloseSound2();
    }
    if (isPlay == true)
    {
    mdxs.PlaySound2(isLoop);
    }
    if (isStop == true)
    {
    mdxs.StopSound2();
    }
    }

    }

    上記のように、SOUND系命令の種類によって処理を分け、下の本処理に移ります

    public partial class MainMDXS2 : Form
    {
    private Audio audio = null;

    public MainMDXS2()
    {

    }
    public void SetSound2(string uri)
    {
    this.Sound_Load2(uri);
    }
    public void CloseSound2()
    {
    this.Sound_Closed2();
    }
    public void PlaySound2(bool isLoop)
    {
    if (isLoop == true)
    this.Sound_Play_Loop2();
    else
    this.Sound_Play2();
    }
    public void StopSound2()
    {
    this.Sound_Stop2();
    }
    private void Sound_Load2(string uri)
    {
    try
    {
    audio = new Audio(uri);
    }
    catch (Exception ex)
    {
    // 失敗
    MessageBox.Show(ex.ToString(), "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }

    }
    private void Sound_Closed2()
    {
    // オーディオの破棄
    if (audio != null)
    {
    audio.Dispose();
    }

    }
    private void Sound_Play2()
    {
    if (audio != null)
    {
    // 再生位置を一番最初に設定
    audio.CurrentPosition = 0.0;

    // 再生
    audio.Play();
    }
    }
    private void Sound_Stop2()
    {
    if (audio != null)
    {
    // 停止
    audio.Stop();←ここでエラーが出ます
    }
    }
    private void Sound_Play_Loop2()
    {
    if (audio != null)
    {
    // 再生位置を一番最初に設定
    audio.CurrentPosition = 0.0;

    // 再生
    audio.Play();
    audio.Ending += new EventHandler(OnAudioEnding);
    }

    }
    private void OnAudioEnding(object ob, EventArgs e)
    {
    if (audio != null)
    {
    // 再生位置を一番最初に設定
    audio.CurrentPosition = 0.0;
    audio.Play();
    }
    }
    }

    このようなプログラムなのですが、参照するメモリの位置がおかしいのか、上記のエラーが出ます
    mp3.MIDIファイルを再生したいので、DirectX.DirectSoundではなくDirectX.AudioVideoPlaybackを使っています

    どなたか解決策の分かる方がいたら、どうか教えてください

    2012年11月27日 10:26

すべての返信

  • Subjectはもう少しまともにしてください。たとえばコンパイラを自作していることは今回の質問に関係ありますか? 問題点をきちんと切り分けていない、つまり質問者さん自身が何が問題なのか理解していないからこのような質問になるのです。

    DirectX.AudioVideoPlayback単独でも問題が出るのか、それともコンパイラとやらで使ったときにのみ問題が出るのか、そこを切り分けてください。

    その上で、Managed DirectXはもうすでにサポートされていません。動作しなくても何も言えません。

    2012年11月27日 10:53
  • どういった種類のプログラムを作っているか言っておいた方が、要件が伝わりやすいと思ったのですが……
    私の見当違いでしたら申し訳ありません
    もう一度、私に出来る限り簡潔に質問します

    質問の最初に書いたような命令が作りたいですが、エラーが発生します
    プロジェクトのビルド自体は正常にできました
    エラーはビルドしたコンパイラとやらで、SOUNDPLAY (ファイル名)を記述した文字列を読み込みメディアを再生した後、SOUNDSTOP (ファイル名)でメディアを停止しようとすると起こります

    DirectX.AudioVideoPlayback単独に問題があるのかは私には分かりません

    私にはAudioVideoPlaybackを使って、メディアを操作する命令を作る出来るのかが分かりません
    そもそもC#でそういった命令が作れるのかも分かりません

    ですが、私自身にあまりプログラムに関する知識がないので、C#やMangaedDirectXが悪いのではなく、自分の書いたコードに問題があると思いました
    知識不足な為問題の要点が分からず、メディア操作命令に関連したプログラムをほぼ全て載せました

    もし私の書いたコードに誤りがあれば教えてください
    2012年11月27日 11:47
  • コンパイラを作っている人がそのような切り分けもできないというのは理解に苦しみます。
    2012年11月27日 13:43
  • 作ったプログラムに対して、なぜ動かないかをソースコード一式を渡して投げかける行為は、丸投げとも呼ばれますし、実際、お金を取れるような仕事です。
    フォーラムに対して、コードを提示して「誤りを教えてください」というスタンスでは敬遠されますよ。

    さて、AccessViolationException が出るとのことですが、その止まったときに audio はどのようになっているか、確認しましたか?
    その止まる行にブレークポイントをセットして、そこに来たときに audio がどのようになっているか確認しましたか?

    このように、自分のプログラムをまずはデバッグしてください。
    そして、何が起きているのかを推測してください。その上で、得られた事実を元にポイントを絞った質問は答えられる人がいるかもしれません。

    あと、佐祐理さんも言われていますが、タイトルは要約しましょう。
    説明は本文に書けばよいので、タイトルは本当にポイントを絞った部分を取り出すと読み手にとってもわかりやすくなります。
    たとえば、「DirectX の Audio で停止しようとした際に例外が出る」であれば、スレッドを開く前にある程度内容をとらえられますよね。

    2012年11月27日 13:46
    モデレータ
  • 私も以前に似たようなことがありました。

    同様の症状で参考になるかどうかはわかりませんが

    単純にパソコンのスペックが足りなかったの原因でした。

    メモリなのかグラボなのかよくわかりませんが

    スペックがいいパソコンでデバッグしたら改善した記憶があります。

    2012年12月9日 2:39
  • 「コンパイラ」とはどういう意味で使ってますか? 開発者なら、以下のページの説明にあるような、ソースをオブジェクトコードに変換するプログラムと理解するはずです。

    コンパイラ
    http://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9

    掲示板で用語を間違えると話が通じなくなりますので、ご注意ください。

    2012年12月9日 2:59