トップページ > 記事閲覧
C#版のLoadSoundMemByMemImage呼び出しで例外
名前:zzz 日時: 2021/05/22 17:53

下記コードにより音楽ファイルの読み込み・再生を試みたところ例外が発生してしまいます。 環境: Windows 10 Pro Visual Studio Community 2019 DxLibDotNet version 3_22c (C#) 構成:x86 (32bitアプリケーション) 対象フレームワーク:.NET Framework 4.5 コード: byte[] mp3Data = File.ReadAllBytes(mp3FileName); int handle; GCHandle h = GCHandle.Alloc(mp3Data, GCHandleType.Pinned); try { handle = DX.LoadSoundMemByMemImage(h.AddrOfPinnedObject(), (ulong)mp3Data.Length); // 例外 } finally { h.Free(); } DX.PlaySoundMem(handle, DX.DX_PLAYTYPE_LOOP, 1); 例外: 発生箇所:コード上「// 例外」と示した箇所 メッセージ: PInvoke 関数 'DxLibDotNet!DxLibDLL.DX::dx_LoadSoundMemByMemImage_x86' がスタックを不安定にしています。 PInvoke シグネチャがアンマネージ ターゲット シグネチャに一致していないことが原因として考えられます。 呼び出し規約、および PInvoke シグネチャのパラメーターがターゲットのアンマネージ シグネチャに一致していることを確認してください。 知見が乏しく、推測になり恐縮ですが DxLibDotNet.dll の定義 public static int LoadSoundMemByMemImage(IntPtr FileImage, ulong FileImageSize); は public static int LoadSoundMemByMemImage(IntPtr FileImage, int FileImageSize); が正しいのではないでしょうか よろしくおねがいします。
メンテ

Page: 1 |

Re: C#版のLoadSoundMemByMemImage呼び出しで例外 ( No.1 )
名前:管理人 日時:2021/06/06 04:12

ご返信が大変遅くなり申し訳ありません ご指摘の通り LoadSoundMemByMemImage の引数 FileImageSize が問題でした ただ、C++版の引数である size_t は 32bit版では unsigned int、 64bit版では unsigned __int64 となっているので、一律に ulong としてしまうと やはり問題が発生してしまいます というわけで、32bitの環境で呼ばれた場合は uint に、64bitの環境で呼ばれた場合は ulong になるように修正しましたので、よろしければお試しください m(_ _;m https://dxlib.xsrv.jp/temp/DxLibDotNet.zip // Windows版 .NET用 # < 他スレッドの方へ > # 現在作業時間が非常に少なくなっています # 投稿の順番でご返信しますので今暫くお待ち下さい m(_ _)m
メンテ
Re: C#版のLoadSoundMemByMemImage呼び出しで例外 ( No.2 )
名前:zzz 日時:2021/06/07 10:01

ご対応いただきありがとうございます。 ご提供いただいた DxLibDotNet.zip に差し替えて試してみましたが やはり「PInvoke 関数 'DxLibDotNet!DxLibDLL.DX::dx_LoadSoundMemByMemImage_x86' がスタックを不安定にしています。」という例外が発生してしまいます。 DxLibDotNet.dll を dnSpy に掛けてみたところ // Token: 0x060013D2 RID: 5074 [DllImport("DxLib.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "dx_LoadSoundMemByMemImage")] private static extern int dx_LoadSoundMemByMemImage_x86(IntPtr FileImage, ulong FileImageSize, int BufferNum, int UnionHandle); // Token: 0x060013D3 RID: 5075 [DllImport("DxLib_x64.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "dx_LoadSoundMemByMemImage")] private static extern int dx_LoadSoundMemByMemImage_x64(IntPtr FileImage, ulong FileImageSize, int BufferNum, int UnionHandle); となっており _x86 版も ulong FileImageSize になっているように見受けられました。 また、試しに以下のコードを実行してみたところ、例外が発生することなく音楽の再生に成功しました。 コード: [DllImport("DxLib.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "dx_LoadSoundMemByMemImage")] private static extern int My_dx_LoadSoundMemByMemImage_x86(IntPtr FileImage, uint FileImageSize, int BufferNum, int UnionHandle); //private static extern int My_dx_LoadSoundMemByMemImage_x86(IntPtr FileImage, ulong FileImageSize, int BufferNum, int UnionHandle); // original 〜〜〜 byte[] mp3Data = File.ReadAllBytes(mp3FileName); int handle; GCHandle h = GCHandle.Alloc(mp3Data, GCHandleType.Pinned); try { handle = My_dx_LoadSoundMemByMemImage_x86(h.AddrOfPinnedObject(), (uint)mp3Data.Length, 3, -1); } finally { h.Free(); } DX.PlaySoundMem(handle, DX.DX_PLAYTYPE_LOOP, 1); 勘でやっているのでこれが正しいのかはよくわかっていません... 実は現在 DxLib v3.20f を使用していまして、 先日ふと最新版の DxLib v3.22c を試してみようとしたところ本件の事象に遭遇し、本スレッドを立てた次第です。 (3.20f では本件の事象は発生しません) なので当面は v3.20f を継続してこのまま使い続けることに致します。 管理人様におかれましては、どうか余裕があるときにご対応いただけたら当方幸いでございます。 よろしくお願いします。
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存