简体   繁体   English

C ++:MP3分配中无法解析的外部

[英]C++: Unresolved Externals in MP3 assignment

I'm working on a MP3 player for an assignment. 我正在为任务分配MP3播放器。 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 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 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. 让我知道我是否省略了太多。

Your problem is that you have variables and functions declared inside Song , but are defined at namespace level. 您的问题是您在Song内声明了变量和函数,但在名称空间级别定义了这些变量和函数。 This makes them different entities, and so definitions for the declarations in Song are never found. 这使它们成为不同的实体,因此从未找到Song中声明的定义。

static char songListFile_[ENTRY_SZ] = "";
static char currentMP3_[ENTRY_SZ] = "";
static void ClearListFile() {/*...*/}

These should be changed. 这些应该改变。 Removing static and prefixing the surrounding class Song should fix it. 删除static并为周围的Song类添加前缀应该对其进行修复。

char Song::songListFile_[ENTRY_SZ] = "";
char Song::currentMP3_[ENTRY_SZ] = "";
void Song::ClearListFile() {/*...*/}

You only need the static inside the class definition. 您只需要在类定义中使用static Outside it, you're using a different meaning of the static keyword. 在它外面,您使用的是static关键字的不同含义 I think you have more instances like this outside the code you posted, but it shouldn't be difficult to find them. 我认为您在发布的代码之外还有更多这样的实例,但是找到它们并不难。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM