DirectSound ラッパーを作成しようとしています。そのため、dsound.h ファイルの Cominterfaces を C# にインポートする必要があります。現在、IDirectSoundBuffer に取り組んでいます。これは次のように宣言されます。
DEFINE_GUID(IID_IDirectSoundBuffer, 0x279AFA85, 0x4981, 0x11CE, 0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60);
#undef INTERFACE
#define INTERFACE IDirectSoundBuffer
DECLARE_INTERFACE_(IDirectSoundBuffer, IUnknown)
{
// IUnknown methods
STDMETHOD(QueryInterface) (THIS_ __in REFIID, __deref_out LPVOID*) PURE;
STDMETHOD_(ULONG,AddRef) (THIS) PURE;
STDMETHOD_(ULONG,Release) (THIS) PURE;
// IDirectSoundBuffer methods
STDMETHOD(GetCaps) (THIS_ __out LPDSBCAPS pDSBufferCaps) PURE;
STDMETHOD(GetCurrentPosition) (THIS_ __out_opt LPDWORD pdwCurrentPlayCursor, __out_opt LPDWORD pdwCurrentWriteCursor) PURE;
STDMETHOD(GetFormat) (THIS_ __out_bcount_opt(dwSizeAllocated) LPWAVEFORMATEX pwfxFormat, DWORD dwSizeAllocated, __out_opt LPDWORD pdwSizeWritten) PURE;
STDMETHOD(GetVolume) (THIS_ __out LPLONG plVolume) PURE;
STDMETHOD(GetPan) (THIS_ __out LPLONG plPan) PURE;
STDMETHOD(GetFrequency) (THIS_ __out LPDWORD pdwFrequency) PURE;
STDMETHOD(GetStatus) (THIS_ __out LPDWORD pdwStatus) PURE;
STDMETHOD(Initialize) (THIS_ __in LPDIRECTSOUND pDirectSound, __in LPCDSBUFFERDESC pcDSBufferDesc) PURE;
STDMETHOD(Lock) (THIS_ DWORD dwOffset, DWORD dwBytes,
__deref_out_bcount(*pdwAudioBytes1) LPVOID *ppvAudioPtr1, __out LPDWORD pdwAudioBytes1,
__deref_opt_out_bcount(*pdwAudioBytes2) LPVOID *ppvAudioPtr2, __out_opt LPDWORD pdwAudioBytes2, DWORD dwFlags) PURE;
STDMETHOD(Play) (THIS_ DWORD dwReserved1, DWORD dwPriority, DWORD dwFlags) PURE;
STDMETHOD(SetCurrentPosition) (THIS_ DWORD dwNewPosition) PURE;
STDMETHOD(SetFormat) (THIS_ __in LPCWAVEFORMATEX pcfxFormat) PURE;
STDMETHOD(SetVolume) (THIS_ LONG lVolume) PURE;
STDMETHOD(SetPan) (THIS_ LONG lPan) PURE;
STDMETHOD(SetFrequency) (THIS_ DWORD dwFrequency) PURE;
STDMETHOD(Stop) (THIS) PURE;
STDMETHOD(Unlock) (THIS_ __in_bcount(dwAudioBytes1) LPVOID pvAudioPtr1, DWORD dwAudioBytes1,
__in_bcount_opt(dwAudioBytes2) LPVOID pvAudioPtr2, DWORD dwAudioBytes2) PURE;
STDMETHOD(Restore) (THIS) PURE;
};
だから私はこれを次のように翻訳しようとしました:
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid("279AFA85-4981-11CE-A521-0020AF0BE560")]
public interface IDirectSoundBuffer : IUnknown
{
//int QueryInterface(ref Guid guid, out IntPtr comObject);
//int AddReference();
//int Release();
//IDirectSoundBuffer methods
void GetCaps([MarshalAs(UnmanagedType.LPStruct)] DSBufferCaps pDSBufferCaps); //TODO
void GetCurrentPosition([Out] out UInt32 pdwCurrentPlayCursor, [Out] out UInt32 pdwCurrentWriteCursor);
void GetFormat([Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "AMEngine.Wave.WaveFormatMarshaler")] out AMEngine.Wave.WaveFormat pwfxFormat,
int dwSizeAllocated, [Out] out int pdwSizeWritten); //TODO implement
[return: MarshalAs(UnmanagedType.I4) /*See http://msdn.microsoft.com/en-us/library/aa288468%28v=vs.71%29.aspx */]
Int32 GetVolume();
[return: MarshalAs(UnmanagedType.I4)]
Int32 GetPan();
[return: MarshalAs(UnmanagedType.I4)]
Int32 GetFrequency();
[return: MarshalAs(UnmanagedType.I4)]
Int32 GetStatus();
void Initialize([In, MarshalAs(UnmanagedType.Interface)] IDirectSound pDirectSound, [In] DSBufferDescription pcDSBufferDesc);
void Lock(int dwOffset, int dwBytes,
[Out] out IntPtr ppvAudioPtr1, [Out] out int pdwAudioBytes1,
[Out] out IntPtr ppvAudioPtr2, [Out] out int pdwAudioBytes2,
DSBLock dwFlags );
void Play(int dwReserved1, int dwPriority, DSBPlayFlags dwFlags);
void SetCurrentPosition(int dwNewPosition);
void SetFormat([In] AMEngine.Wave.WaveFormat pcfxFormat);
void SetVolume(int lVolume);
void SetPan(int lPan);
void SetFrequency(int dwFrequency);
void Stop();
void Unlock([In] IntPtr pvAudioPtr1, int dwAudioBytes1,
[In] IntPtr pvAudioPtr2, int dwAudioBytes2);
void Restore();
}
IUnknown はこのインターフェイスです:
[Guid("00000000-0000-0000-C000-000000000046")]
public interface IUnknown
{
int QueryInterface(ref Guid gidd, out IntPtr ppvObject);
int AddRef();
int Release();
}
インターフェイス IDirectSoundBuffer 自体が機能します。しかし、SetVolume のような一部のメンバーでは、例外 E_NONINTERFACE が発生し、QueryInterface を実装する必要があると通知されました。そこで、IUnknown を作成しました。しかし、私は好きなことを何でも試すことができます。それは決して機能しません。上記の解決策を試すと、プライマリ バッファを再生しようとすると例外が発生します。これは、primarybufferdescritption に他のフラグを設定する必要があることを示しています。しかし、他のフラグを設定すると、バッファを作成しようとすると例外が発生します。最終的に、IUnknown のものをすべて削除すると、オーディオを再生できますが、ボリューム、パンを設定することはできません...しかし、再生することはできます。これまでのところ動作します。
数週間前からこの問題を解決しようとしていますが、解決策が見つかりません。だからあなたは私の最後の希望です:(