unresolved external
I've been writing some code to parse a .WAV file written in cannonical form. The data from the .WAV file is simply dumped into a matrix created using the TNT library (http://math.nist.gov/tnt/). However, when I compile the code, I get the following error from the compiler (VC++ 2005):
------ Build started: Project: WaveReaderClass, Configuration: Debug Win32 ------
Linking...
test.obj : error LNK2019: unresolved external symbol "public: class TNT::Array1D<short> * __thiscall WaveReader::getSoundData(void)" (?getSoundData@WaveReader@@QAEPAV?$Array1D@F@TNT@@XZ) referenced in function _main
P:\WaveReaderClass\WaveReaderClass\Debug\WaveReaderClass.exe : fatal error LNK1120: 1 unresolved externals
Build log was saved at "file://p:\snowDensity\WaveReaderClass\WaveReaderClass\WaveReaderClass\Debug\BuildLog.htm"
WaveReaderClass - 2 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Where am I going wrong? I've searched the forums on GameDev.net. Apparently, I need to include the TNT::Array1D class so that it is visible to both the function definitions in the header files and main() in the driver class. Here are the other files that I am working with.
////////////////////////////////////////////////////////////////
//Program to test the waveReader classes
#include <iostream>
#include <cstdlib>
//Template Numerical Toolkit
#include "\common\tnt\tnt_array1d.h"
//Header file
#include "waveReader.h"
int main()
{
WaveReader readWave;
TNT::Array1D<short int> testSoundData;
if (!readWave.loadFile("test_1.wav"))
{
std::cout << "\nThe .WAV file could not be loaded\n";
exit(1);
}
//Test out the classes
std::cout << "The length of the file is " << readWave.getFileLength() << "\n";
std::cout << "The format tag of the file is " << readWave.getFormatTag() << "\n";
std::cout << "The number of channels in the file is " << readWave.getChannelNum() << "\n";
std::cout << "The number of samples per second in the file is " << readWave.getSamplesPerSecond() << "\n";
std::cout << "The sample rate * block align of the file is " << readWave.getSampleRateTimesBlockAlign() << "\n";
std::cout << "The channel descriptor is " << readWave.getChannelDescriptor() << "\n";
std::cout << "The function to get the number of bits per sample is " << readWave.getBitsPerSample() << "\n";
std::cout << "The length of the data block is " << readWave.getLengthOfDataBlock() << "\n";
std::cout << "The sound data array is:\n";
//Set the pointer in this file to the memory location of the data array
testSoundData = *readWave.getSoundData();
for (int i = 0; i < testSoundData.dim(); i++)
std::cout << testSoundData << "\n";
std::cout << "That's all folks.\n";
return 0;
}//end main
////////////////////////////////////////////////////////////////
/Program to be able to read the cannonical .WAV file
//Assume that the data is stored as 2's complement signed integers
#include <iostream>
#include <fstream>
//Template Numerical Toolkit
#include "\common\tnt\tnt_array1d.h"
//Header Files
#include "WaveReader.h"
//Pointer of array containing sound data
TNT::Array1D<short int> soundData;
//Default constructor
WaveReader::WaveReader()
{
}
//Function to read the sound wave from the file
bool WaveReader::loadFile(std::string fileName)
{
std::ifstream inFile(fileName.c_str(), std::ios::in | std::ios::binary);
if (!inFile)
{
//Indicate that the file could not be opened
return false;
}
//Begin parsing the file
inFile.seekg(4);
inFile.read((char *)&fileLengthSubtract8, 4);
fileLength = fileLengthSubtract8 + 8;
inFile.seekg(20);
inFile.read((char *)&formatTag, 2);
inFile.read((char *)&channelNumber, 2);
inFile.read((char *)&samplesPerSecond, 4);
inFile.read((char *)&sampleRateTimesBlockAlign, 4);
inFile.read((char *)&channelDescriptor, 2);
inFile.read((char *)&bitsPerSample, 2);
inFile.seekg(40);
inFile.read((char *)&lengthOfDataBlock, 4);
//Extract all of the sample data
int counter = 0;
int dataBlockSampleNum = lengthOfDataBlock / 2;
while (true)
{
inFile.read((char *)&dataValue, 2);
if (inFile.eof())
break;
soundData[counter++] = dataValue;
}
//Close the file
inFile.close();
return true;
}//end loadFile
//Function to get the length of the file
int WaveReader::getFileLength()
{
return fileLength;
}
//Function to get the format tag of the file
int WaveReader::getFormatTag()
{
return formatTag;
}
//Function to get the number of channels
int WaveReader::getChannelNum()
{
return channelNumber;
}
//Function to get the samples per second
int WaveReader::getSamplesPerSecond()
{
return samplesPerSecond;
}
//Function to get the sample rate * block align
int WaveReader::getSampleRateTimesBlockAlign()
{
return sampleRateTimesBlockAlign;
}
//Function to get the channel descriptor
int WaveReader::getChannelDescriptor()
{
return channelDescriptor;
}
//Function to get the number of bits per sample
int WaveReader::getBitsPerSample()
{
return bitsPerSample;
}
//Function to get the length of the data block
int WaveReader::getLengthOfDataBlock()
{
return lengthOfDataBlock;
}
//Function that returns a reference to the sound data array
TNT::Array1D<short int> *getSoundData()
{
return &soundData
}
////////////////////////////////////////////////////////////////
//Header file for the WaveReader class
#ifndef WAVEREADER_H
#define WAVEREADER_H
class WaveReader
{
public:
//Constructor
WaveReader();
//Function to load the file
bool loadFile(std::string fileName);
//Accessor to get the file length
int getFileLength();
//Accessor to get the format tag of the file
int getFormatTag();
//Accessor to get the number of channels
int getChannelNum();
//Accessor to get the number of samples per second
int getSamplesPerSecond();
//Accessor to get the sample rate * block align
int getSampleRateTimesBlockAlign();
//Accessor to get the channel descriptor
int getChannelDescriptor();
//Accessor to hold the bits per sample
int getBitsPerSample();
//Accessor to get the length of the data block
int getLengthOfDataBlock();
//Function to get the matrix containing all of the data
TNT::Array1D<short int> *getSoundData();
private:
//RIFF Header
//Variable to hold the fileLength - 8
int fileLengthSubtract8;
//Variable to hold the fileLength
int fileLength;
//FMT Chunk
//Variable to hold the format tag (1 = PCM)
int formatTag;
//Variable to hold the number of channels
int channelNumber;
//Variable to hold the samples per second
int samplesPerSecond;
//Variable to hold the sampleRate * block align
int sampleRateTimesBlockAlign;
//Variable to hold the channel descriptor
int channelDescriptor;
//Variable to hold the bits per sample
int bitsPerSample;
//Data Chunk
//Variable to hold the length of the data block
int lengthOfDataBlock;
//Variable to hold a 16-bit data value as two's complement
short int dataValue;
};//end class WaveReader
#endif
////////////////////////////////////////////////////////////////
Thank you!
Are you sure (a) you've included the right file (b) you've spelt the name of the function right (c) you've included the right namespace, if necessary (d) you have the right version of the library you're using? The error is a simple 'cannot find' one, so it must be something along those lines.
Thanks for the reply! I have checked the includes for all of the files, and it seems that everything should work. I think that the problem is associated with a type of cyclic dependency, where the linker has included the TNT::Array1D class twice, and thus cannot reference the proper function (because there are two copies included in the object file). How do I ensure that the compiler 'knows' that the TNT::Array1D class is referred to in the header file (without getting some sort of linker error)?
Once again, thank you for your help!
Once again, thank you for your help!
If you had 2 copies of the function, you'd have been given a different error message. This message is because it can't even find 1 copy of the function.
The problem is that the function you have written is a global function, but the function you have tried to use is a member function, which naturally doesn't exist.
The problem is that the function you have written is a global function, but the function you have tried to use is a member function, which naturally doesn't exist.
Sometimes, error messages are difficult to decipher because they contain too much information. The problem is exactly what it says -- you are missing the function WaveReader::getSoundData().
However, you implemented the function getSoundData(). I assume that's a typo.
Also, when posting code you should enclose it using
However, you implemented the function getSoundData(). I assume that's a typo.
Also, when posting code you should enclose it using
and
or [ source ] and [ /source ].
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement