0

私は VC++2010 でゲーム プロジェクトを持っており、SDL、オーディオを最初に使用するように更新しています。プロジェクトを最初から再構築すると、Audio クラスでいくつかのリンカ エラーが発生します。Audio.cpp に移動して任意の場所に空白を追加すると (ファイルを再度保存する必要があります)、ビルドすると正常にコンパイルされます。これはとても神秘的だと思います。Visual Studio を数回再起動しましたが、この動作は持続します。

私は C++ プログラミングの初心者です。私の経験のほとんどは、高水準言語 (C#、Python) に関するものです。助けてくれてありがとう。

ここにAudio.hがあります

#pragma once

#include "SDL/SDL.h"
#include "SDL/SDL_thread.h"
#include "SDL/SDL_mixer.h"

#include <string>
#include <vector>

using namespace std;

class AudioTrack {
public:
    string Description;
        string Filename;
        Mix_Music* track;
        AudioTrack(const string& Description, const string& Filename){
                this->Description = Description;
                this->Filename = Filename;
                track = Mix_LoadMUS(Filename.c_str());
        }
};

class AudioEffect {
public:
        string Description;
        string Filename;
        Mix_Chunk* effect;
        AudioEffect(const string& Description, const string& Filename){
                this->Description = Description;
                this->Filename = Filename;
                effect = Mix_LoadWAV(Filename.c_str());
        }
};

class Audio {
private:
        static vector<AudioTrack> tracks;
        static vector<AudioEffect> effects; 

        static void AddTrack(const string& Description, const string& Filename);
        static void AddEffect(const string& Description, const string&  Filename);

public:
        //initializes and loads sound
        static void Init();

        static void Free();

        //plays continuously until there is more music.
        static void PlayTrack(const string& Description);

        //plays once
        static void PlayEffect(const string&  Description);
};

ここにAudio.cppがあります

#include "Audio.h"
#include <stdio.h>


//void musicDone() {
//  Mix_HaltMusic();
//  Mix_FreeMusic(music);
//  music = NULL;
//} 

vector<AudioTrack> Audio::tracks;
vector<AudioEffect> Audio::effects;  

void Audio::AddTrack(const string& Description, const string& Filename) {
    AudioTrack newTrack = AudioTrack(Description,Filename);
        tracks.push_back(newTrack);
}

void Audio::AddEffect(const string& Description, const string& Filename) {
        AudioEffect newEffect = AudioEffect(Description,Filename);
        effects.push_back(newEffect);
}  

void Audio::Init() {
        //SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
        SDL_Init(SDL_INIT_AUDIO);

        int audio_rate = 22050;
        Uint16 audio_format = AUDIO_S16; 
        int audio_channels = 2;
        int audio_buffers = 4096;

        if(Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers)) {
                printf("Unable to open audio!\n");
                exit(1);
        }

        //Descriptions for all tracks and effects
        AddTrack("Title","Title.wav");
        AddTrack("Game","Sample_Track_1_V2.wav");

        AddEffect("Collision","Collision_1.wav");

}

void Audio::Free() {
        //TODO

        //free music


}   

void Audio::PlayTrack(const string& Description) {
        for (int i = 0; i < tracks.size(); i++) {
                if (tracks[i].Description.compare(Description) == 0) {
                        Mix_PlayMusic(tracks[i].track, -1);
                        /*Mix_HookMusicFinished(musicDone);*/
                }
        }
} 

void Audio::PlayEffect(const string& Description) {
        for (int i = 0; i < effects.size(); i++) {
                if (effects[i].Description.compare(Description) == 0) {
                        Mix_PlayChannel(-1,effects[i].effect, 0);
                }
        }
}

以下は、新しいビルドで発生するリンカー エラーです。

1>Debug\//Audio.obj : warning LNK4042: object specified more than once; extras ignored
1>LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library
1>Draw.obj : error LNK2019: unresolved external symbol "public: static void __cdecl Audio::PlayTrack(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?PlayTrack@Audio@@SAXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function "void __cdecl setMode(int)" (?setMode@@YAXH@Z)
1>SampleDraft.obj : error LNK2001: unresolved external symbol "public: static void __cdecl Audio::PlayTrack(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?PlayTrack@Audio@@SAXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
1>SampleDraft.obj : error LNK2019: unresolved external symbol "public: static void __cdecl Audio::Init(void)" (?Init@Audio@@SAXXZ) referenced in function _SDL_main
1>C:\Dev Code\Sample\Sample 2013 Draft\\Bin\SampleDraft.exe : fatal error LNK1120: 3 unresolved externals

Audio.cpp に空白を追加して単純にビルドした後に表示される警告を次に示します。ビルドは成功し、機能しています。

1>Debug\//Audio.obj : warning LNK4042: object specified more than once; extras ignored
1>LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library
1>  SampleDraft.vcxproj -> C:\Dev Code\Sample\Sample 2013 Draft\\Bin\SampleDraft.exe

編集:これは完全に無関係かもしれません。ほとんどの開発では、ソリューション エクスプローラーのヘッダー ファイルとコード ファイルは、表示のために別の仮想フォルダーにありました。ただし、数週間前に、それらはすべて 1 つのフォルダーに表示されるように切り替えられたようです。

4

2 に答える 2

2

出力の最初の行は、原因に関する警告を表示しようとしているようです。

1>Debug//Audio.obj: 警告 LNK4042: オブジェクトが複数回指定されました。エキストラは無視

どうやら、リンカーには複数の Audio.obj オブジェクト ファイルが渡されています。ディストリビューションのどこかに (ファイル エクスプローラーで調べて) 定義のない "古い" ものがあるようです。正しい Audio.cpp を更新してコンパイルすると、それらを含む Audio.obj が作成されます。

于 2013-07-08T00:37:51.277 に答える