Link ошибки

  • Автор темы Firefox
  • Дата начала
F

Firefox

#1
Здравствуйте. Создала отдельную программу для записи данных с микрофона. все работает и хорошо. далее понадобилось подключить классы этой программы в основную(большую) программу. в основной программе так же используется работа с DirectSound. но стало выдавать вот такие ошибки
error LNK2001: unresolved external symbol ___argc
error LNK2001: unresolved external symbol ___wargv
error LNK2005: "void * __cdecl operator new(unsigned int)" (??2@YAPAXI@Z) already defined in msvcprtd.lib(newop_s.obj)
error LNK2005: "void * __cdecl operator new[](unsigned int)" (??_U@YAPAXI@Z) already defined in msvcprtd.lib(newaop_s.obj)
error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPAX@Z) already defined in MSVCRTD.lib(MSVCR71D.dll)

вот код подключаемого класса:
C++:
///.h
#include <QtGui/QWidget>
#include <iostream> 
#include <QMessageBox>
#include "Wavwrite.h"
#include <mmreg.h>
#include <dsound.h>
#include "initguid.h"
#include <QTextCodec>
#include <QFile>

#define NUM_REC_NOTIFICATIONS 16
class Mic_recod
{
public: 
Mic_recod();
~Mic_recod();
LPDIRECTSOUNDCAPTURE		g_pDSCapture;
LPDIRECTSOUNDCAPTUREBUFFER	g_pDSBCapture;
LPDIRECTSOUNDNOTIFY			g_pDSNotify;
LPTSTR						strFileName1;
WAVEFORMATEX*				g_pwfxInput;
DSBPOSITIONNOTIFY			g_aPosNotify[ NUM_REC_NOTIFICATIONS + 1 ]; 
HANDLE						g_hNotificationEvents[2]; 
BOOL						g_abInputFormatSupported[16];
DWORD						g_dwCaptureBufferSize;
DWORD						g_dwNextCaptureOffset;
DWORD						g_dwNotifySize;
bool						g_bRecording;
CWaveSoundWrite*			g_pWaveSoundWrite;

bool write_data_to_file(QString file_way);
void position_writing();

HRESULT StopBuffers();
HRESULT InitNotifications();
HRESULT CreateCaptureBuffer();
HRESULT RecordCapturedData();
private:
void Start_Func(bool g_bRecording);


};
//.cpp
#include "stdafx.h"
#include "Mic_record.h"

Mic_recod::Mic_recod()
{
g_pWaveSoundWrite= new CWaveSoundWrite();

ZeroMemory( &g_aPosNotify, sizeof(DSBPOSITIONNOTIFY) * 
(NUM_REC_NOTIFICATIONS + 1) );
g_pDSCapture		= NULL;
g_pDSBCapture		= NULL;
g_pDSNotify			= NULL;
g_pwfxInput			= NULL;

g_dwCaptureBufferSize	= 0;
g_dwNextCaptureOffset	= 0;
g_dwNotifySize			= 0;
g_pwfxInput= new WAVEFORMATEX;
g_pwfxInput->wFormatTag=WAVE_FORMAT_PCM;
g_pwfxInput->nSamplesPerSec = 44100;
g_pwfxInput->wBitsPerSample = 16;
g_pwfxInput->nChannels = 2;
g_pwfxInput->nBlockAlign = g_pwfxInput->nChannels * ( g_pwfxInput->wBitsPerSample >> 3 );
g_pwfxInput->nAvgBytesPerSec = g_pwfxInput->nBlockAlign * g_pwfxInput->nSamplesPerSec;

// Создание объекта IDirectSoundCapture для используемого устройства записи
if( FAILED( DirectSoundCaptureCreate( NULL, &g_pDSCapture, NULL ) ) )
throw;

g_hNotificationEvents[0] = CreateEvent( NULL, FALSE, FALSE, NULL );
g_hNotificationEvents[1] = CreateEvent( NULL, FALSE, FALSE, NULL );

strFileName1=L"Sound1.wav";
g_pWaveSoundWrite->Open(strFileName1, g_pwfxInput);
}
Mic_recod::~Mic_recod()
{
// Уничтожение интерфейсов DirectSound
if( g_pDSNotify )
g_pDSNotify-> Release();

if( g_pDSBCapture )
g_pDSBCapture-> Release();

if( g_pDSCapture )
g_pDSCapture-> Release();

if( g_pWaveSoundWrite )
delete	g_pWaveSoundWrite;

if( g_pwfxInput )
delete	g_pwfxInput;

CloseHandle(g_hNotificationEvents[0]);
CloseHandle(g_hNotificationEvents[1]);
}
UINT WaitThreadProc1(LPVOID param)
{
Mic_recod*	dlg	= (Mic_recod*) param;
HANDLE*		g_hNotificationEvents = dlg->g_hNotificationEvents;

DWORD  dwResult;

while( dlg->g_bRecording ) 
{ 
dwResult =WaitForSingleObject(g_hNotificationEvents, INFINITE);
/*dwResult =MsgWaitForMultipleObjects( 2,g_hNotificationEvents, 
FALSE, INFINITE, QS_ALLEVENTS );*/
if( dwResult == WAIT_OBJECT_0 )
{
// Отмечено событие g_hNotificationEvents[0]

// DirectSound только что записал очередной фрагмент аудио информации.
// Необходимо освободить циклический буфер и записать
// его содержимое в аудио файл

if( FAILED(dlg->RecordCapturedData()))
{
QMessageBox::warning(0,"error","Ошибка при работе с объектами извещений DirectSound. Приложение завершило свою работу.", "Использование DirectSound");
}
}
}

return	0;
}
void Mic_recod::Start_Func(bool g_bRecording)
{
if( g_bRecording==false)
{
// Останавливает запись и считывает несохранённую
// аудио информацию
StopBuffers();
}
else
{
if( FAILED(CreateCaptureBuffer()))
{
delete	g_pWaveSoundWrite;
//delete	g_pDSB_Record;

}
HRESULT hr;
hr=g_pDSBCapture->Start( DSCBSTART_LOOPING );
// Инициализация поцесса записи в буфер
if( hr==S_OK)
{
AfxBeginThread( WaitThreadProc1,this);
}
else
QMessageBox::warning( 0,"error","Ошибка при инициализации записи в буфер DirectSound.Приложение завершило свою работу.", "Использование DirectSound");
}

g_bRecording = !g_bRecording;
}

HRESULT Mic_recod::StopBuffers()
{
if( NULL == g_pDSBCapture )
return S_OK;

g_pDSBCapture-> Stop();

// Чтение информации из буфера записи
RecordCapturedData();



return S_OK;
}
HRESULT Mic_recod::RecordCapturedData() 
{
HRESULT hr;
VOID*  pbCaptureData	= NULL;
DWORD  dwCaptureLength;
VOID*  pbCaptureData2  = NULL;
DWORD  dwCaptureLength2;
VOID*  pbPlayData	  = NULL;
UINT	dwDataWrote;
DWORD  dwReadPos;
DWORD  dwCapturePos;
LONG lLockSize;

if( !g_pDSBCapture )
return S_FALSE;

if( !g_pWaveSoundWrite )
return S_FALSE;

if( FAILED( hr = g_pDSBCapture->GetCurrentPosition( &dwCapturePos, &dwReadPos ) ) )
return hr;

lLockSize = dwReadPos - g_dwNextCaptureOffset;
if( lLockSize < 0 )
lLockSize += g_dwCaptureBufferSize;

// Выравнивание границы блока
lLockSize -= (lLockSize % g_dwNotifySize);

if( lLockSize == 0 )
return S_FALSE;

/*char szRecordMsg[200];
sprintf( szRecordMsg, "Writing %5d bytes to file from capture buffer starting at offset %d\n", lLockSize, g_dwNextCaptureOffset );
OutputDebugString( szRecordMsg );*/

// Блокировка буфера записи
if( FAILED( hr = g_pDSBCapture->Lock( g_dwNextCaptureOffset, lLockSize, 
&pbCaptureData, &dwCaptureLength, 
&pbCaptureData2, &dwCaptureLength2, 0L ) ) )
return hr;

// Запись аудио информации в файл
if( FAILED( hr = g_pWaveSoundWrite->Write( dwCaptureLength, 
(BYTE*)pbCaptureData, 
&dwDataWrote ) ) )
return hr; 

// Разблокирование буфера записи
g_pDSBCapture->Unlock( pbCaptureData, dwCaptureLength, NULL, 0 );

// Перемещение начальной позиции записи
g_dwNextCaptureOffset += dwCaptureLength; 
g_dwNextCaptureOffset %= g_dwCaptureBufferSize; // Циклический буфер

if( pbCaptureData2 != NULL )
{
// Запись информации в файл
if( FAILED( hr = g_pWaveSoundWrite->Write( dwCaptureLength2, 
(BYTE*)pbCaptureData2, 
&dwDataWrote ) ) )
return hr; 

// Разблокирование буфера записи
g_pDSBCapture->Unlock( pbCaptureData2, dwCaptureLength2, NULL, 0 );

// Перемещение начальной позиции записи
g_dwNextCaptureOffset += dwCaptureLength2; 
g_dwNextCaptureOffset %= g_dwCaptureBufferSize; // Циклический буфер
}

return S_OK;
}
//-----------------------------------------------------------------------------
// Имя:			CreateCaptureBuffer()
// Описание:	Создаёт буфер записи и устанавливает его формат
//-----------------------------------------------------------------------------
HRESULT Mic_recod::CreateCaptureBuffer()
{
HRESULT hr;
DSCBUFFERDESC dscbd;

if( g_pDSNotify )
g_pDSNotify-> Release();

if( g_pDSBCapture )
g_pDSBCapture-> Release();

// Установка размера извещения

if( g_pwfxInput->nAvgBytesPerSec > 8192 )
g_dwNotifySize	= g_pwfxInput->nAvgBytesPerSec >> 3;
else
g_dwNotifySize	= 1024;

g_dwNotifySize -= g_dwNotifySize % g_pwfxInput->nBlockAlign;  

// Установка размера буфера
g_dwCaptureBufferSize = g_dwNotifySize * NUM_REC_NOTIFICATIONS;

// Создание буфера записи
ZeroMemory( &dscbd, sizeof(dscbd) );
dscbd.dwSize		= sizeof(dscbd);
dscbd.dwBufferBytes = g_dwCaptureBufferSize;
dscbd.lpwfxFormat  = g_pwfxInput; // Установка формата в процессе создания.

if( FAILED( hr = g_pDSCapture->CreateCaptureBuffer( &dscbd, &g_pDSBCapture, NULL ) ) )
return hr;

g_dwNextCaptureOffset = 0;

if( FAILED( InitNotifications() ) )
return hr;

return S_OK;
}
//-----------------------------------------------------------------------------
// Имя:			InitNotifications()
// Описание:	Инициализирует процесс посылки извещений, обрабатываемых
//				функцией WinMain()
//-----------------------------------------------------------------------------
HRESULT Mic_recod::InitNotifications()
{
HRESULT hr; 

if( NULL == g_pDSBCapture )
return E_FAIL;

// Создание объекта события, отмечаемого при остановке записи
if( FAILED( hr = g_pDSBCapture->QueryInterface( IID_IDirectSoundNotify, 
(VOID**)&g_pDSNotify ) ) )
return hr;

// Определение позиции отметки события
for( INT i = 0; i < NUM_REC_NOTIFICATIONS; i++ )
{
g_aPosNotify[i].dwOffset = (g_dwNotifySize * i) + g_dwNotifySize - 1;
g_aPosNotify[i].hEventNotify = g_hNotificationEvents[0];			 
}

g_aPosNotify[i].dwOffset	 = DSBPN_OFFSETSTOP;
g_aPosNotify[i].hEventNotify = g_hNotificationEvents[1];

// Установка позиций отметки событий. Сообщения об отметке событий обра
// обрабатываются в функции WinMain()
if( FAILED( hr = g_pDSNotify->SetNotificationPositions( NUM_REC_NOTIFICATIONS + 1, 
g_aPosNotify ) ) )
return hr;

// Сохранение формата буфера записи в переменной g_pCaptureWaveFormat
if( g_pwfxInput )
delete	g_pwfxInput;

g_pwfxInput = new WAVEFORMATEX;
ZeroMemory( g_pwfxInput, sizeof(WAVEFORMATEX) );
g_pDSBCapture->GetFormat( g_pwfxInput, sizeof(WAVEFORMATEX), NULL );

return S_OK;
}
// класс подключаемый к классу Mic_recod для создание структуры wave-файла//
//.h
//-----------------------------------------------------------------------------
// Файл:		WavWrite.h
//
// Описание:	Файл заголовка класса CWaveSoundWrite
//
//-----------------------------------------------------------------------------
#ifndef WAVE_WRITE_H
#define WAVE_WRITE_H
#include "windows.h"
#include <mmsystem.h>


//-----------------------------------------------------------------------------
// Имя:			Класс CWaveSoundWrite
// Описание:	Класс, осуществляющий запись аудио информации в файл
//-----------------------------------------------------------------------------
class CWaveSoundWrite
{
public:
HMMIO	m_hmmioOut;			// Мультимедийный дескриптор файла
MMCKINFO m_ckOut;			// Инфоромация о вложенном блоке формата RIFF
MMCKINFO m_ckOutRIFF;		// Используется при открытии аудио файла
MMIOINFO m_mmioinfoOut;

CWaveSoundWrite();
~CWaveSoundWrite();

HRESULT Open( LPTSTR, WAVEFORMATEX* );
HRESULT Reset();
HRESULT Write( UINT, BYTE*, UINT* );
HRESULT Close( DWORD );

};

#endif WAVE_WRITE_H

//.cpp
//-----------------------------------------------------------------------------
// Файл:		WavWrite.cpp
//
// Описание:	Запись аудио информации в файл
//
//-----------------------------------------------------------------------------

#include "stdafx.h"
#include "WavWrite.h"

//-----------------------------------------------------------------------------
// Имя:			CWaveSoundWrite()
// Описание:	Конструктор класса
//-----------------------------------------------------------------------------
CWaveSoundWrite::CWaveSoundWrite()
{
m_hmmioOut = NULL;
}

//-----------------------------------------------------------------------------
// Имя:			~CWaveSoundWrite()
// Описание:	Деструктор класса
//-----------------------------------------------------------------------------
CWaveSoundWrite::~CWaveSoundWrite()
{
Close( 0 );
}

//-----------------------------------------------------------------------------
// Имя:			Open()
// Описание:	Открывает аудио файл для записи
//-----------------------------------------------------------------------------
HRESULT CWaveSoundWrite::Open( LPTSTR strFileName, WAVEFORMATEX *pwfxDest )
{
HRESULT	hr;
HMMIO	hmmioOut = NULL;

if( m_hmmioOut )
Close( 0 );

if( NULL == ( hmmioOut = mmioOpen( strFileName, NULL, MMIO_ALLOCBUF | 
MMIO_READWRITE | 
MMIO_CREATE ) ) )
return 0;


DWORD	dwFactChunk;	// Содержимое вложенного блока fact.
// До вызова функции WaveCloseWriteFile содержит
// неопределённую информацию.

dwFactChunk = (DWORD)-1;

// Создание вложенного блока RIFF с идентификатором формата 'WAVE'.
m_ckOutRIFF.fccType = mmioFOURCC('W', 'A', 'V', 'E');	  
m_ckOutRIFF.cksize = 0;

if( 0 != mmioCreateChunk( hmmioOut, &m_ckOutRIFF, MMIO_CREATERIFF ) )
{
mmioClose( hmmioOut, 0 );
return E_FAIL;
}

// Созданный вложенный блок 'RIFF' раскрыт.
// В нём создаётся вложенный блок 'fmt '. Поскольку его размер известен, его
// необходимо указать в объекте структуры MMCKINFO, чтобы MMIO не определял бы
// его при выходе из данного вложенного блока.
m_ckOut.ckid = mmioFOURCC('f', 'm', 't', ' ');
m_ckOut.cksize = sizeof(PCMWAVEFORMAT);  

if( 0 != mmioCreateChunk( hmmioOut, &m_ckOut, 0 ) )
{
mmioClose( hmmioOut, 0 );
return E_FAIL;
}

// Во вложенный блок 'fmt ' записывается объект структуры PCMWAVEFORMAT. 
if( mmioWrite( hmmioOut, (HPSTR) pwfxDest, 
sizeof(PCMWAVEFORMAT)) != sizeof(PCMWAVEFORMAT))
{
mmioClose( hmmioOut, 0 );
return E_FAIL;
}

// Выход из вложенного блока 'fmt ' во вложенный блок 'RIFF'.
if( 0 != mmioAscend( hmmioOut, &m_ckOut, 0 ) )
{
mmioClose( hmmioOut, 0 );
return E_FAIL;
}

m_hmmioOut = hmmioOut;

if( FAILED( hr = Reset() ) )
return hr;

return hr;
}

//-----------------------------------------------------------------------------
// Имя:			Reset()
// Описание:	Устанавливает текущую позицию записи на начало блока
//-----------------------------------------------------------------------------
HRESULT CWaveSoundWrite::Reset()
{
// Создание вложенного блока 'data', в который будет записана аудио информация. 
m_ckOut.ckid = mmioFOURCC('d', 'a', 't', 'a');
m_ckOut.cksize = 0;

if( 0 != mmioCreateChunk( m_hmmioOut, &m_ckOut, 0 ) ) 
return E_FAIL;

if( 0 != mmioGetInfo( m_hmmioOut, &m_mmioinfoOut, 0 ) )
return E_FAIL;

return S_OK;
}

//-----------------------------------------------------------------------------
// Имя:			Write()
// Описание:	Сохраняет аудио информацию в файле
//-----------------------------------------------------------------------------
HRESULT CWaveSoundWrite::Write( UINT nSizeToWrite, BYTE* pbData, UINT* pnSizeWrote )
{
UINT cT;

*pnSizeWrote = 0;

for( cT = 0; cT < nSizeToWrite; cT++ )
{	  
if( m_mmioinfoOut.pchNext == m_mmioinfoOut.pchEndWrite )
{
m_mmioinfoOut.dwFlags |= MMIO_DIRTY;
if( 0 != mmioAdvance( m_hmmioOut, &m_mmioinfoOut, MMIO_WRITE ) )
return E_FAIL;
}

*((BYTE*)m_mmioinfoOut.pchNext) = *((BYTE*)pbData+cT);
(BYTE*)m_mmioinfoOut.pchNext++;

(*pnSizeWrote)++;
}

return S_OK;
}

//-----------------------------------------------------------------------------
// Имя:			Close()
// Описание:	Закрывает аудио файл, открытый для записи.
//-----------------------------------------------------------------------------
HRESULT CWaveSoundWrite::Close( DWORD dwSamples )
{
m_mmioinfoOut.dwFlags |= MMIO_DIRTY;

if( 0 != mmioSetInfo( m_hmmioOut, &m_mmioinfoOut, 0 ) )
return E_FAIL;

// Выход из вложенного блока 'data'. При этом размер записанной информации
// сохраняется в поле размера вложенного блока 'data'.
if( 0 != mmioAscend( m_hmmioOut, &m_ckOut, 0 ) )
return E_FAIL;

// Выход из вложенного блока 'RIFF'. При этом размер записанной информации
// сохраняется в поле размера вложенного блока 'RIFF'.
if( 0 != mmioAscend( m_hmmioOut, &m_ckOutRIFF, 0 ) )
return E_FAIL;

mmioClose( m_hmmioOut, 0 );

return S_OK;  
}
если закоментировать функцию AfxBeginThread( WaitThreadProc1,this); ошибки пропадают. но тогда не функционирует класс. помогите пожалуйста.
 

lazybiz

Well-known member
03.11.2010
1 339
0
#2
А зачем ты в первом файле делаешь инклуды Qt ? Их удаление возможно и не исправит ошибку, но как говорится рыба гниет с головы.
 
F

Firefox

#3
Дело в том что основной проект написан на Qt. в подключаемом классе используются некоторый функции qt, например генерация сообщения об ошибки. хотя идея может быть хорошая(основной файл библиотек qt - #include <QtGui/QWidget> подключается получается дважды). проверю.
 
F

Firefox

#4
А зачем ты в первом файле делаешь инклуды Qt ? Их удаление возможно и не исправит ошибку, но как говорится рыба гниет с головы.
Ошибка была исправлена путем изменение настроек проекта для работы с dll библиотеками. на Shead DLL