2012-09-30 111 views
3

下面的代碼,Delphi下XE2的Win32編譯和Win下運行7 64位,執行行 「AudioSessionManager2.GetSessionEnumerator」 時產生以下的異常「Project22.exe引發的異常類$ 0000005與消息‘訪問衝突在0x7027edb2:地址0x0051ced6寫’」異常調用 「IAudioSessionManager2.GetSessionEnumerator()」 在Delphi XE2

我的異常類或他們的意思是缺乏的,所以我不知道是什麼的知識是什麼例外的意思或如何去解決它。

這裏是引發異常(斷言用於調試代碼)的代碼:我使用的是從MFPack on Google Code核心音頻定義

var 
    HRES: HRESULT; 
    DeviceEnumerator: IMMDeviceEnumerator; 
    DefaultDevice: IMMDevice; 
    AudioSessionManager2: IAudioSessionManager2; 
    Enumerator: IAudioSessionEnumerator; 
begin 

    CoInitialize(nil); 

    HRES := CoCreateInstance(CLSID_MMDeviceEnumerator, nil, CLSCTX_ALL, IID_IMMDeviceEnumerator, DeviceEnumerator); 
    Assert(Succeeded(HRES)); 

    HRES := DeviceEnumerator.GetDefaultAudioEndpoint(eRender, eMultimedia, DefaultDevice); 
    Assert(Succeeded(HRES)); 

    HRES := DefaultDevice.Activate(IID_IAudioSessionManager2, CLSCTX_ALL, nil, IUnknown(AudioSessionManager2)); 
    Assert(Succeeded(HRES)); 

    HRES := AudioSessionManager2.GetSessionEnumerator(Enumerator); // <- EXCEPTION HERE 
    Assert(Succeeded(HRES)); 

    [snip] 

,與IAudioSessionManager2和IAudioSessionEnumerator接口尋找如下:

IAudioSessionManager2 = interface(IUnknown) 
['{77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F}'] 
    function GetSessionEnumerator(out SessionEnum: IAudioSessionEnumerator): HResult; stdcall; 
    function RegisterSessionNotification(SessionNotification: IAudioSessionNotification): HResult; stdcall; 
    function UnregisterSessionNotification(SessionNotification: IAudioSessionNotification): HResult; stdcall; 
    function RegisterDuckNotification(const sessionID: LPCWSTR; const duckNotification: IAudioVolumeDuckNotification): HResult; stdcall; 
    function UnregisterDuckNotification(const duckNotification: IAudioVolumeDuckNotification): HResult; stdcall; 
end; 

IAudioSessionEnumerator = interface(IUnknown) 
['{E2F5BB11-0570-40CA-ACDD-3AA01277DEE8}'] 
    function GetCount(out SessionCount: integer): HResult; stdcall; 
    function GetSession(const SessionCount: integer; out Session: IAudioSessionControl): HResult; stdcall; 
end; 

我相信接口是正確定義的,我也仔細檢查了GUID。由於在Visual Studio 2012(Win32項目)下執行的指令序列相同,我懷疑問題出在我的代碼(這裏沒有什麼疑問),Core Audio接口定義或Delphi。在VS運行的C++代碼如下:

IMMDeviceEnumerator *DeviceEnumerator = NULL; 
IMMDevice* DefaultDevice = NULL; 
IAudioSessionManager2* AudioSessionManager = NULL; 
IAudioSessionEnumerator* Enumerator = NULL; 
HRESULT HR; 

HR = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&DeviceEnumerator); 
HR = DeviceEnumerator->GetDefaultAudioEndpoint(eRender, eMultimedia, &DefaultDevice); 
HR = DefaultDevice->Activate(__uuidof(IAudioSessionManager2), CLSCTX_ALL, NULL,(void**)&AudioSessionManager); 
HR = AudioSessionManager->GetSessionEnumerator(&Enumerator); 

用C++代碼我可以正確檢索會話枚舉和使用getCount將等

我花了無數的時間試圖找出什麼是錯的我的代碼和我仍然無能,所以任何幫助將不勝感激。

+0

你不應該是類型鑄造DefaultDevice.Activate()''到的IUnknown''最後一個參數,把它作爲其原始類型只是就像你使用'CoCreateInstance()'做的一樣。你也應該使用'OleCheck()'而不是'Assert()'。 –

+0

謝謝你的建議,雷米。 Activate()被聲明爲將IUnknown作爲其最後一個參數,這就是爲什麼我這樣做。我確實嘗試將聲明更改爲其他各種類型,包括「out ppInterface」,但沒有任何工作。我只是在C++ Builder中嘗試了C++代碼,並且它的工作原理也是如此。在這方面工作的幾天,我不能得到它的工作。我想在C++中使用DLL可能會更容易,因爲我無法承受更多的時間。 –

+0

最後一個參數應該是一個無類型的'out',就像'CoCreateInstance()'使用的一樣。另一種方法是使用'@'運算符傳遞變量,就像在C++中一樣,使用'PPointer'。 –

回答

6

根據MSDN,IAudioSessionManager2應該IAudioSessionManager繼承:

type 
    IAudioSessionManager2 = interface(IAudioSessionManager) 
    ... 
+0

你說得對。根據您鏈接的MSDN頁面,「IAudioSessionManager2」基於「IAudioSessionManager」和「IUnknown」中的「IAudioSessionManager」。 –

+0

這工作完美!我將回顧其他接口的這種疏忽,並希望能夠聯繫維護他們的人員。 –