[英]C++: Unresolved Externals in MP3 assignment
我正在為任務分配MP3播放器。 我不斷收到以下錯誤:
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)
據我了解,這類錯誤源於不包括函數聲明,聲明但未實現,拼寫錯誤等。在這里我錯過了什么? 由於這是一項任務,因此我將發布我認為導致該問題的最少代碼。
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);
}
讓我知道我是否省略了太多。
您的問題是您在Song
內聲明了變量和函數,但在名稱空間級別定義了這些變量和函數。 這使它們成為不同的實體,因此從未找到Song
中聲明的定義。
static char songListFile_[ENTRY_SZ] = "";
static char currentMP3_[ENTRY_SZ] = "";
static void ClearListFile() {/*...*/}
這些應該改變。 刪除static
並為周圍的Song
類添加前綴應該對其進行修復。
char Song::songListFile_[ENTRY_SZ] = "";
char Song::currentMP3_[ENTRY_SZ] = "";
void Song::ClearListFile() {/*...*/}
您只需要在類定義中使用static
。 在它外面,您使用的是static
關鍵字的不同含義 。 我認為您在發布的代碼之外還有更多這樣的實例,但是找到它們並不難。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.