Re: SetLoopPosSoundMemでアクセス違反 ( No.1 ) |
- 名前:hima 日時:2010/06/01 22:51
手元で少し弄った所、メモリ位置を動かさなくとも改善しました。
変更点としては、
○元のソース
・同じ音楽ファイルを二つ読み込み、二つともループを設定
・そのうち一つは周波数を変え、音を高くした
○変更後
・別々の音楽ファイル(外部で既に周波数を変更した)を読み込み、二つともループを設定
・ソフト側での周波数の変更は無し
二度同じものを行う、周波数を変更するあたりが怪しいかもしれません。
|
Re: SetLoopPosSoundMemでアクセス違反 ( No.2 ) |
- 名前:いっち 日時:2010/06/01 23:42
その事象は条件さえそろえば100%起こるのでしょうか?
また、DebugビルドReleaseビルド両方で再現するのでしょうか?
|
Re: SetLoopPosSoundMemでアクセス違反 ( No.3 ) |
- 名前:hima 日時:2010/06/02 10:04
>その事象は条件さえそろえば100%起こるのでしょうか?
手元で試した限りでは100%起こります。
>また、DebugビルドReleaseビルド両方で再現するのでしょうか?
同じソースコードでもビルド時は起こらず、ビルドせずに前回のビルドを実行すると発生することがあります。
現在また状況を脱してしまったためDebug/Releaseは試していませんが、恐らくReleaseでやると発生しないと思います。
#上に改善したと書きましたが、先程再発しました。関係ないようです。
#或いは他の起動ソフトと関係があるのかもしれません
|
Re: SetLoopPosSoundMemでアクセス違反 ( No.4 ) |
- 名前:いっち 日時:2010/06/02 18:33
> 手元で試した限りでは100%起こります。
> 同じソースコードでもビルド時は起こらず、ビルドせずに前回のビルドを実行すると発生することがあります。
矛盾する気がするのですが・・・。
|
Re: SetLoopPosSoundMemでアクセス違反 ( No.5 ) |
- 名前:hima 日時:2010/06/02 23:04
「一度既にビルドした」という条件を満たしていれば100%起こります。
|
Re: SetLoopPosSoundMemでアクセス違反 ( No.6 ) |
- 名前:いっち 日時:2010/06/03 21:45
下記のようなテストコードを作って再現を試みましたがうまくいきませんでした。
環境:WinXP Pro SP3 + VS2008EE SP1 + DxLib 3.02c
追加で質問です。
この事象はDebugビルドReleaseビルド関係なく起こるとの事ですが、
デバッグ無し実行(Ctrl+F5)でも起きるのでしょうか?
//-- テストコード --//
#include "DxLib.h"
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
ChangeWindowMode( TRUE );
if ( DxLib_Init( ) == -1 ) return -1;
SetDrawScreen( DX_SCREEN_BACK );
int SoundHandle = LoadSoundMem( "BGM098.ogg" );
SoundHandle = LoadSoundMem( "BGM098.ogg" ); // この行を増減させて再現を試みる
SetLoopPosSoundMem( 20000, SoundHandle );
PlaySoundMem( SoundHandle, DX_PLAYTYPE_LOOP );
while ( ProcessMessage( ) == 0 ) {
if ( CheckHitKey( KEY_INPUT_ESCAPE ) ) break;
}
DxLib_End( );
return 0;
}
※追記
管理人さんに直接プロジェクトとデータを送付して調査して頂いたほうが良いかもしれません。
|
Re: SetLoopPosSoundMemでアクセス違反 ( No.7 ) |
- 名前:管理人 日時:2010/06/06 02:52
メールを拝見いたしました
添付していただいた再現用のソースで私の環境でもエラーの再現ができ、原因が分かり
修正することが出来ました、ありがとうございます
そして、ご迷惑をお掛けして申し訳ありませんでした m(_ _;m
修正版をアップしましたのでよろしければお使い下さい
http://homepage2.nifty.com/natupaji/DxLib/DxLibVCTest.exe // VisualC++ 用
http://homepage2.nifty.com/natupaji/DxLib/DxLibBCCTest.exe // BorlandC++ 用
(中身を既存のライブラリのファイルに上書きして、BCCをお使いの
場合は『再構築』、VCをお使いの場合は『リビルド』をして下さい)
> いっちさん
ご対応ありがとうございます
|
Re: SetLoopPosSoundMemでアクセス違反 ( No.8 ) |
- 名前:hima(解決) 日時:2010/06/06 10:00
お疲れ様です。修正版のほう試してみました。
複雑な条件故100%とは言い切れませんが、今のところ再現ソース・製作物共にこちらでもエラーは出ないようです。
難しい問題にも関わらず迅速に対応して下さり誠にありがとうございました。
|
Re: SetLoopPosSoundMemでアクセス違反 ( No.9 ) |
- 名前:いっち 日時:2010/06/06 12:26
管理人さん >
もし可能でしたら、発生条件や原因など教えて頂けますでしょうか?
|
Re: SetLoopPosSoundMemでアクセス違反 ( No.10 ) |
- 名前:管理人 日時:2010/06/06 12:49
> himaさん
正常に動作しているようでなによりです
何かありましたらご連絡をください m(_ _)m
> いっちさん
はい、ちょっと長くなりますが・・・
発生条件は SetCreateSoundDataType で DX_SOUNDDATATYPE_MEMNOPRESS を指定した状態( デフォルトの状態 )で
LoadSoundMem 等で作成したサウンドハンドルに対して SetLoopPosSoundMem を使用した場合です
原因については、まず前提として SetLoopPosSoundMem などのループ位置指定機能は DX_SOUNDDATATYPE_MEMNOPRESS 以外の
ストリーミングタイプのサウンドデータに対してのみ可能なので、非ストリーミングタイプのサウンドハンドルが
渡された場合は最初にストリーミングタイプのサウンドハンドルを新規に作成し( ただ、サウンドハンドルとしての数値は一緒 )
そのサウンドハンドルが元のサウンドハンドルのサウンドデータを使用するようにした上で改めて SetLoopPosSoundMem の処理を行います
サウンドハンドルとしての数値は一緒なのですが、そのサウンドハンドルの実データを格納しているメモリ領域は元のサウンドハンドル
とは別の位置になる可能性があるので非ストリームタイプのサウンドハンドルをストリーミングタイプのサウンドハンドルとして
生まれ変わらせた後の SetLoopPosSoundMem の実質の処理では新規に作成されたサウンドハンドルの実データが格納されている
メモリ領域にアクセスする必要があります
ですが、修正前のプログラムでは SetLoopPosSoundMem の実質の処理を行う段階で既に削除された非ストリーミングタイプの
サウンドハンドルの実データが格納されていたメモリ領域にアクセスしていて、それが不正なメモリアクセスの原因となっています
一見まともに動作してしまっていたケースでは、削除された非ストリーミングタイプのサウンドハンドルのデータが格納されていた
メモリ領域と全く同じ領域に新たに作成されたストリーミングタイプのサウンドハンドルの実データが格納されていたと考えられます
|
Re: SetLoopPosSoundMemでアクセス違反 ( No.11 ) |
- 名前:いっち(解決) 日時:2010/06/06 13:19
お忙しい中、ご教授ありがとうございます。
おかげさまで理解することが出来ました。
対応お疲れ様でした。
|