PDA

Visualizza la versione completa : [C++] problemi di casting tra PBYTE e LPSTR


gianvituzzi
11-01-2010, 22:14
Salve,

in questo momento per capire meglio il concetto di classe e programmazione orientata agli oggetti in C++ sto scrivendo una classe per usare in modo più semplice la waveForm API di windows.

la classe si chiama waveCapture ed è composta naturalmente da due files:

waveCapture.h
waveCapture.cpp

I metodi della classe sono i seguenti:



// Costruttori e distruttore
waveCapture();
waveCapture(DWORD dwSamplePerSec, WORD wBitsPerSample, WORD nChannels);
~waveCapture();

// Start Capturing WAVE
BOOL start();
BOOL start(WORD uDevice);
BOOL start(WORD uDevice, DWORD dwBufferLength, DWORD dwNumBuffers);

// Get Buffer (return bytes captured)
DWORD getBuffer(PBYTE pWAVBuffer);

// Stop Capturing
BOOL stop();


di seguito mostro come si usa la classe in main()



#include "waveCapture.h"

int main()
{
waveCapture* pwc = new waveCapture(); // Default: 44100, 16 (bit), 2 (STEREO)

pwc->start(0, 176400, 3); // (microfono interno, 176400 bytes, 3 buffers)

PBYTE pWAVBuffer = new BYTE[176400];
DWORD dwBytesRecorded = 0;

dwBytesRecorded = pwc->getBuffer(pWAVBuffer);
dwBytesRecorded = pwc->getBuffer(pWAVBuffer);

//...etc...oppure:

while( dwBytesRecorded = pwc->getBuffer(pWAVBuffer) > 0 )
{
//...do something with pWAVBuffer...
}

pwc->stop();
return 0;
}


Quindi ogni volta che chiamo getBuffer(); passo un puntatore ad un blocco di memoria BYTE che verrà riempito dalla fun<ione. La funzione poi ritornerà il numero di bytes realmente catturati. La funzione è bloccante e ritorna il primo buffer pronto. (all'interno viene usata la CALLBACK_EVENT)

questa è la struttura della classe nel file header:



class waveCapture
{
public:
// Constructors:
waveCapture();
~waveCapture();
waveCapture(DWORD, WORD, WORD);

// Methods:
BOOL start();
BOOL start(WORD);
BOOL start(WORD, DWORD, DWORD);
BOOL stop();
DWORD getBuffer(PBYTE);
private:
HANDLE hevent;
HWAVEIN hwi;
WAVEFORMATEX wf;
WAVEHDR *buff;
DWORD _dwBufferCount;
DWORD dwTotalBufferLength;
}


il lavoro è svolto per la maggior parte da start() e getBuffer() che hanno in comune /WAVEHDR *buff/, /HWAVEIN hwi/ e sopratutto /WAVEHDR *buff/

Ora vi mostro la funzione membro getBuffer() che è quella che mi da problemi (in quanto ritorna 0 e un puntatore vuoto):



DWORD waveCapture::getBuffer(PBYTE pWAVBuffer)
{
DWORD _dwBytesRecorded = 0;

// CALLBACK EVENT
WaitForSingleObject(hevent, INFINITE);

if(buff[_dwBufferCount].dwFlags & WHDR_DONE)
{
_dwBytesRecorded = buff[_dwBufferCount].dwBytesRecorded;
pWAVBuffer = (PBYTE)buff[_dwBufferCount].lpData;
waveInAddBuffer(hwi, &buff[_dwBufferCount], sizeof(WAVEHDR));
}

if(_dwBufferCount == __dwNumBuffers -1)
{
_dwBufferCount = 0;
} else {
_dwBufferCount++;
}

dwTotalBufferLength += _dwBytesRecorded;
return _dwBytesRecorded;
}


volevo sapere se sto facendo bene il casting:



PBYTE pWAVBuffer = (PBYTE)buff[_dwBufferCount].lpData;


in quanto buff.lpData è nativo in LPSTR ed io dovrei portarlo a PBYTE

per completezza posto anche il codice della funzione membro start() (sintetizzata)



BOOL waveCapture::start()
{
// ...let's get straight to the gist...

// Define WAVEFORMATEX Structure (WAVEFORMATEX wf)
(...)

// Create event:
hevent = CreateEvent(NULL,0,0,NULL);

// WaveInOpen
waveInOpen(&hwi,uDevice,(LPWAVEFORMATEX)&wf,(DWORD)hevent,0,CALLBACK_EVENT);

// Define WAVEHDR Structure:
buff = new WAVEHDR[dwNumBuffers];

// Push buffers:
waveInPrepareHeader(hwi, &buff[i], sizeof(WAVEHDR));
waveInAddBuffer(hwi, &buff[i], sizeof(WAVEHDR));

// Start capturing...
waveInStart(hwi);
_dwBufferCount = 0;
return true;
}


forse sono andato un pò troppo per le lunghe...

grazie

gianvituzzi
12-01-2010, 00:45
ho pensato che forse la CALLBACK_EVENT è settata male. mi spiego:



// Create event:
hevent = CreateEvent(NULL,0,0,NULL);

// WaveInOpen
waveInOpen(&hwi,uDevice,(LPWAVEFORMATEX)&wf,(DWORD)hevent,0,CALLBACK_EVENT);

// Define WAVEHDR Structure:
buff = new WAVEHDR[dwNumBuffers];

// Push buffers:
waveInPrepareHeader(hwi, &buff[k], sizeof(WAVEHDR));
waveInAddBuffer(hwi, &buff[k], sizeof(WAVEHDR));

// Start capturing...
waveInStart(hwi);


vengono immessi nel sistema n buffers e poi inizio a catturare (waveInStart) in questo momento il sistema mi sta già notificando che i primi buffers sono pronti tramite la CALLBACK_EVENT (hevent) ma la funzione finisce li...i buffers vengono ottenuti in un'altra funzione, allora mi domandavo se fosse non dovessi settare diversamente la createEvent() ovvero che non notifichi finchè non ho chiamato la funzione membro getBuffer()

ma non sono molto sicuro

gianvituzzi
12-01-2010, 02:46
ad esempio, il codice seguente non mi cambia il contenuto del puntatore:



#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

typedef char* STRING;
BOOL saluto(PBYTE);

int main()
{

PBYTE marameo = new BYTE[10];
saluto(marameo);

printf("%s\n", marameo);

system("pause");
return 0;
}

BOOL saluto(PBYTE a)
{
STRING kk = "Hello World!";
a = (PBYTE)kk;
return true;
}

gianvituzzi
12-01-2010, 04:42
pardon per l'ultima cosa scritta, ho risolto tutto con memcpy()

Loading