下面的代碼,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將等
我花了無數的時間試圖找出什麼是錯的我的代碼和我仍然無能,所以任何幫助將不勝感激。
你不應該是類型鑄造DefaultDevice.Activate()''到的IUnknown''最後一個參數,把它作爲其原始類型只是就像你使用'CoCreateInstance()'做的一樣。你也應該使用'OleCheck()'而不是'Assert()'。 –
謝謝你的建議,雷米。 Activate()被聲明爲將IUnknown作爲其最後一個參數,這就是爲什麼我這樣做。我確實嘗試將聲明更改爲其他各種類型,包括「out ppInterface」,但沒有任何工作。我只是在C++ Builder中嘗試了C++代碼,並且它的工作原理也是如此。在這方面工作的幾天,我不能得到它的工作。我想在C++中使用DLL可能會更容易,因爲我無法承受更多的時間。 –
最後一個參數應該是一個無類型的'out',就像'CoCreateInstance()'使用的一樣。另一種方法是使用'@'運算符傳遞變量,就像在C++中一樣,使用'PPointer'。 –