有人能指出我什麼是錯與此代碼嗎?我在混合使用C++和MC++方面有非常艱苦的經驗。我已經閱讀了很多有關這個主題的博客和教程(通過代表),但現在看起來我的代碼是好的(編譯並且在調試模式下一步一步地運行良好)會崩潰。傳遞一個代表回調到本地C++ API調用
的主要問題是,它需要有一個代表是一個成員函數(其需要訪問其他類成員)。
我記得那裏有waveInProc文檔中的一張紙條,上面說,回調中你不能調用任何系統功能。應該是因爲它試圖使用其他成員,並且託管環境發生在這裏調用其他系統方法,所以應用程序崩潰了?
ref class CWaveIn
{
public:
void CWaveIn::Open(int currentInputDeviceId)
private:
void AllocateBuffer(void);
void WaveInProc(HWAVEIN hwi, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
delegate void CallBack(HWAVEIN hwi, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
CallBack^ myDelegate;
protected:
WAVEFORMATEX* waveFormat;
int bufferDuration; // in seconds
BYTE* waveInBuffer;
int bufferSize;
};
void CWaveIn::AllocateBuffer(void)
{
free(waveInBuffer);
bufferSize = waveFormat->nAvgBytesPerSec * bufferDuration;
waveInBuffer = new BYTE[bufferSize];
Debug::WriteLine("BufferSize: " + bufferSize);
}
void CWaveIn::WaveInProc(HWAVEIN hwi, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
{
switch(uMsg) {
case WIM_CLOSE:
Debug::WriteLine("WIM_CLOSE");
break;
case WIM_DATA:
for(int i=0;i<bufferSize; i++) {
Debug::Write(waveInBuffer[i] + " ");
}
Debug::WriteLine("WIM_DATA");
break;
case WIM_OPEN:
Debug::WriteLine("WIM_OPEN");
break;
}
}
void CWaveIn::Open(int currentInputDeviceId)
{
MMRESULT result = ::waveInOpen(0, currentInputDeviceId, waveFormat, 0, 0, WAVE_FORMAT_QUERY);
Debug::WriteLine(L"CWaveIn::Open() WAVE_FORMAT_QUERY: device " + currentInputDeviceId.ToString());
DebugError(result);
if(result == MMSYSERR_NOERROR)
{
myDelegate = gcnew CallBack(this, &CWaveIn::WaveInProc);
pin_ptr<CallBack^> ptrMyDelegate= &myDelegate;
IntPtr delegatePointer = System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(myDelegate);
HWAVEIN hWaveIn;
MMRESULT result = ::waveInOpen(&hWaveIn, currentInputDeviceId, waveFormat, (DWORD_PTR)delegatePointer.ToPointer(), 0, CALLBACK_FUNCTION | WAVE_FORMAT_DIRECT);
Debug::WriteLine(L"CWaveIn::Open() : device " + currentInputDeviceId.ToString());
DebugError(result);
AllocateBuffer();
WAVEHDR WaveInHdr;
WaveInHdr.lpData = (LPSTR)waveInBuffer;
WaveInHdr.dwBufferLength = bufferSize;
WaveInHdr.dwBytesRecorded=0;
WaveInHdr.dwUser = 0L;
WaveInHdr.dwFlags = 0L;
WaveInHdr.dwLoops = 0L;
::waveInPrepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));
result = ::waveInAddBuffer(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));
result = ::waveInStart(hWaveIn);
Debug::WriteLine(L"CWaveIn::Start() : device " + currentInputDeviceId.ToString());
DebugError(result);
}
}
它可以幫助,如果將提供關於你從調試器獲取時墜毀消息,上線堆棧轉儲ECT一些更多的信息。 – Alon 2010-01-03 09:18:40
現在我想到的一點是,當CWaveIn :: Open調用完成時,pin_ptr超出範圍。那麼,我怎麼能把它固定在課堂上呢? – 2010-01-03 09:20:07
異常碼是C0000005 ACCESS_VIOLATION。 錯誤模塊名稱:msvcrt.dll。 沒有關於該行的信息。在調用回調函數時,可能發生在waveInOpen內部。 它有幫助嗎? – 2010-01-03 09:23:56