I'm working on a MP3 player for an assignment. I keep getting the following errors:
1>A4_main.obj : error LNK2019: unresolved external symbol "public: static void __cdecl Song::ClearListFile(void)" (?ClearListFile@Song@@SAXXZ) referenced in function "void __cdecl DeleteSong(void)" (?DeleteSong@@YAXXZ)
1>A4_main.obj : error LNK2001: unresolved external symbol "public: static char * Song::songListFile_" (?songListFile_@Song@@2PADA)
1>A4_Song.obj : error LNK2001: unresolved external symbol "public: static char * Song::songListFile_" (?songListFile_@Song@@2PADA)
1>A4_Song.obj : error LNK2019: unresolved external symbol __imp__mciSendStringA@16 referenced in function "public: void __thiscall Song::PlaySong(void)" (?PlaySong@Song@@QAEXXZ)
1>A4_Song.obj : error LNK2001: unresolved external symbol "public: static char * Song::currentMP3_" (?currentMP3_@Song@@2PADA)
From what I understand, these sort of errors stem from not including function declarations, declaring but not implementing them, misspelling, etc. What have I missed here? Since this is an assignment, I'll post the bare minimum of the code I think is causing the problem.
A4_main.cpp
#include "A4_LinkedList.h"
#include "A4_Song.h"
#include <iostream>
#include <fstream>
#include <cstdio>
#include <string>
using namespace std;
LinkedList g_list;
void FreeLinkedList();
char DisplayMenu();
void LoadSongFile();
void AddNewSong();
void DeleteSong();
void PlaySong();
void PrintAllSongs();
//stuff
void LoadSongFile()
{
const int SZ = 256;
int songCnt = 0;
ifstream inData;
char buff[SZ];
Song* newSong;
_flushall();
cout << "\nEnter the full file path: ";
cin.getline(Song::songListFile_, SZ);
// Open the file
inData.open(Song::songListFile_);
// Free any memory currently allocated for the word array
FreeLinkedList();
// Loop through file again and allocate memory
while (!inData.eof())
{
// Each time through loop read all 5 entries in each line.
// Songt with the Song name
inData.getline(buff, SZ);
if (buff[0] == 0)
{
// No more words
break;
}
// Create a new Song object
newSong = new Song(buff);
if (newSong == 0)
{
cout << "\nDynamic memory allocation failed.";
break;
}
// Add this Song object to the linked list
g_list.AddLinkToBack(newSong);
songCnt++;
}
inData.close();
cout << "\nLoaded file and read " << songCnt << " Song objects.";
}
void DeleteSong()
{
const int SZ = 256;
bool foundSong = false;
Node* node = g_list.GetFirstNode();
Song* song = 0;
char songFileName[SZ];
_flushall();
// Prompt the user for the name of a song
cout << "\nEnter the song name with extension: ";
cin.getline(songFileName, SZ);
// Loop through the linked list for that song and delete it if it is found.
// If not, print error to console.
while (node != 0)
{
// Cast the void ptr to a song object ptr
song = (Song*)(node->data_);
// Call on the Song class to print the objects contents
if (strcmp(song->GetSongName(), songFileName) == 0)
{
// Set flag and get out of loop
g_list.RemoveThisLink(node);
foundSong = true;
break;
}
// Go to the next node
node = node->next_;
}
if (!foundSong)
{
cout << "\nCould not find that song in list!\n";
}
else
{
// Now that the linked list has been updated need to persist the new
// list to the song file, replacing previous contents.
Song::ClearListFile();
// Now loop through the linked list again, appending the song
// file name to the song list file.
node = g_list.GetFirstNode();
while (node != 0)
{
// Cast the void ptr to a song object ptr then add name to file
song = (Song*)(node->data_);
song->AppendToListFile();
// Go to the next node
node = node->next_;
}
}
}
A4_Song.cpp
#include "A4_Song.h"
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <Windows.h>
using namespace std;
// Store the path name of the song list file
static char songListFile_[ENTRY_SZ] = "";
static char currentMP3_[ENTRY_SZ] = "";
// Static method to empty the song list file
static void ClearListFile()
{
ofstream outFile;
if (songListFile_[0] != 0)
{
// Open for truncate then close again
outFile.open(songListFile_, ios_base::ate);
outFile.close();
}
else
cout << "\nNothing to clear!";
}
void Song::PlaySong()
{
const int BUFF_SZ = 512;
char fullStr[BUFF_SZ];
MCIERROR err;
StopSong();
// Set global variable so we know this file is playing.
// Sandwich the file name in escaped double quotes so
// spaces can be included and don't need to double up
// on the backslashes.
sprintf_s(currentMP3_, ENTRY_SZ, "\"%s\"", songPath_);
sprintf_s(fullStr, BUFF_SZ, "open %s type mpegvideo alias myFile", currentMP3_);
err = mciSendString(fullStr, NULL, 0, 0);
err = mciSendString("play myFile", NULL, 0, 0);
}
Let me know if I've omitted too much.