2012-09-02 54 views
-1

好了,所以我一直在关注这个教程打开文件:http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=4422&lngWId=3无法使用CreateFile函数

现在为止,我已经得到了一切工作,直到我需要的程序在.RAW音频文件加载。

下面是相关代码:

LPSTR loadAudioBlock(const char* filename, DWORD* blockSize) 
{ 
HANDLE hFile = INVALID_HANDLE_VALUE; 
DWORD size = 0; 
DWORD readBytes = 0; 
void* block = NULL; 

//open the file 

if((hFile = CreateFile((LPCWSTR)filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) 
    return NULL; 

// get it's size, allocate memory, and then read it into memory 

size = GetFileSize(hFile, NULL); 
block = HeapAlloc(GetProcessHeap(), 0, size); 
ReadFile(hFile, block, size, &readBytes, NULL); 

CloseHandle(hFile); 
*blockSize = size; 
return (LPSTR)block; 
} 

然后我的主函数调用它:

int _tmain(int argc, _TCHAR* argv[]) 
{ 
HWAVEOUT hWaveOut; //device handle 
WAVEFORMATEX wfx; //struct for format info 
MMRESULT result; // for waveOut return values 
LPSTR block; 
DWORD blockSize; 

// first let's set up the wfx format struct 

wfx.nSamplesPerSec = 44100; // rate of the sample 
wfx.wBitsPerSample = 16; //sample size 
wfx.nChannels = 2; // 2 channels = stereo 
wfx.cbSize = 0; // no extra info 
wfx.wFormatTag = WAVE_FORMAT_PCM; //PCM format 
wfx.nBlockAlign = (wfx.wBitsPerSample >> 3) * wfx.nChannels; 
wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec; 

// then let's open the device 

if(waveOutOpen(&hWaveOut, WAVE_MAPPER, &wfx, 0, 0, CALLBACK_NULL) != MMSYSERR_NOERROR) 
{ 
    fprintf(stderr, "unable to open Wave Mapper device.\n"); 
    Sleep(1000); 
    ExitProcess(1); 
} 

// if no errors then close it 
printf("The Wave Mapper device was opened successfully!\n"); 

//load and play file 
if((block = loadAudioBlock("ding.raw", &blockSize)) == NULL) 
{ 
    fprintf(stderr, "Unable to load file\n"); 
    Sleep(1000); 
    ExitProcess(1); 
} 
writeAudioBlock(hWaveOut, block, blockSize); 
Sleep(1000); 
waveOutClose(hWaveOut); 
return 0; 
} 

每次我运行程序我得到:“无法加载文件”输出。我在我的exe文件的同一目录下有“ding.raw”文件。我也想这样做的完整路径为“C://路径”和“C:/路径”,但那么编译器只是给了我自己无法加载PDB文件更多的错误。

任何想法?我正在使用Visual Studio 2012 Professional IDE和编译器。

+0

当'CreateFile'呼叫失败,使用['GetLastError'](http://msdn.microsoft.com/en-us/library/windows/desktop/ms679360%28v=vs.85%29.aspx)看看你有什么错误。的错误代码的列表可发现[这里](http://msdn.microsoft.com/en-us/library/windows/desktop/ms681381%28v=vs.85%29.aspx)。 –

+0

“Windows”操作系统对路径使用反斜杠。所以完整路径应该是'C:\\ path \\ ding.raw'。 – fasked

+2

我的怀疑是你正在使用宽字符串在文件名中混合正常字符串('const char *'是普通字符串,而'LPCWSTR'是宽字符串)。 –

回答

0
LPSTR loadAudioBlock(const char* filename, DWORD* blockSize) 
{ 
    if((hFile = CreateFile(CA2T(filename), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) 
return NULL; 
} 

查看ATL转换宏:http://msdn.microsoft.com/en-us/library/87zae4a3%28v=vs.80%29.aspx只是铸造const char * LPCWSTR不起作用。

+0

编译器说“CA2W”是一个未声明的标识符。 –

+0

#include 并使用CA2T - 发布已更正。 –

+0

它编译没有错误,但该文件仍未加载。 –

3

而不是使用标准char的,你应该使用例如_TCHARLPCTSTR无处不在。这将使您传递的所有字符串和字符串指针都正确。

看看argv的参数_tmain,你会看到它使用_TCHAR而不是char。这是因为Windows支持普通字符和Unicode字符,具体取决于几个宏。见例如here了解更多信息。

所以要解决什么是可能您的问题(因为你没有得到实际的错误代码,请参阅我的评论大约GetLastError),你应该改变这样的功能:

void *loadAudioBlock(LPCTSTR filename, DWORD* blockSize) 
{ 
    // ... 

    if((hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) 
    return NULL; 

    // ... 
} 

,并调用它像这样:

// ... 

void *block; 

if((block = loadAudioBlock(_T("C:\\path\\ding.raw"), &blockSize)) == NULL) 
{ 
    fprintf(stderr, "unable to open Wave Mapper device, error code %ld.\n", GetLastError()); 
    Sleep(1000); 
    ExitProcess(1); 
} 

// ... 

正如你可以看到我还改变了返回类型,因为它是二进制文件,不会有任何可读的文本。

+0

该文件仍未打开。我只是得到这个错误代码: ERROR_FILE_NOT_FOUND 2(0x2) 系统找不到指定的文件。 所以这并没有多大帮助。 –

+1

@TylerJarjoura即使您提供文件的完整路径?当然,正确的斜杠。 –