C# 将C++代码(COM接口)转换为C

C# 将C++代码(COM接口)转换为C,c#,com,C#,Com,我正在尝试编写DirectSound包装器。因此,我必须将dsound.h文件的ComInterface导入c。我目前正在开发IDirectSoundBuffer。声明如下: DEFINE_GUID(IID_IDirectSoundBuffer, 0x279AFA85, 0x4981, 0x11CE, 0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60); #undef INTERFACE #define INTERFACE IDirectSoundB

我正在尝试编写DirectSound包装器。因此,我必须将dsound.h文件的ComInterface导入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();

}
所以我试着这样翻译:

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。但我可以尝试任何我喜欢的。它永远不起作用。当我尝试上述解决方案时,当我尝试播放主缓冲区时,会出现异常。它告诉我必须为PrimaryBufferDescription设置其他标志。但是如果我设置了其他标志,当我尝试创建缓冲区时,我会得到一个异常。 最后,我得出的结果是,接口声明一定有问题,因为如果我删除所有IUnknown内容,我可以播放音频,但我只是无法设置音量、平移,。。。但是我可以玩,而且到目前为止它还可以用


几个星期以来,我一直试图解决这个问题,但我找不到任何解决办法。所以你是我最后的希望:

你的翻译有很多错误。你自己尝试解决这个问题没有什么意义,这是以前做过的。看一看SharpDX。我看了一看SharpDX,但这不是我要找的。我还看了slimdx。Sharpdx正以另一种方式实现这一点。作者写给我:哦,我知道,源代码的大部分是直接从DirectX C++标题生成的。在每个项目中,都有一个包含生成文件的生成文件夹。但是我真的找不到那些生成的文件。整个项目要复杂得多,因为我需要它。他为HeaderFile编写了某种翻译器,因为他需要更多的接口。那么你能告诉我我的错误吗?