我在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
编辑:这可能完全不相关。对于大多数开发,在解决方案资源管理器中,标题和代码文件位于单独的虚拟文件夹中以便显示。然而,几周前他们似乎转而在一个文件夹中显示。
答案 0 :(得分:2)
看起来你输出的第一行试图给你一个关于原因的警告:
1&gt;调试// Audio.obj:警告LNK4042:指定的对象超过 一旦;附加设备被忽略
显然,链接器正在传递多个Audio.obj对象文件。看起来在某个地方(使用文件浏览器环顾四周)有一个“陈旧”的,没有定义。当您更新并编译正确的Audio.cpp时,会创建一个具有它们的Audio.obj。
答案 1 :(得分:0)
该解决方案与Visual Studio编译器行为有关! (我最初是在2013年担任问题编辑的,但基于@Nevo的评论,我应该将其列为实际答案。)
最初,由于在“添加”->“新建项目”对话框中单击不当,因此将头文件Audio.h
添加为Audio.cpp
。我只是重命名了文件并继续编码。但是,似乎Visual Studio也将文件类型存储在项目文件(.vcxproj)中。 Visual Studio仍在尝试将Audio.h
编译为代码。我通过在解决方案资源管理器->常规->项目类型中右键单击Audio.h
来解决此问题,并将其设置为“ C / C ++标头”而不是“ C / C ++编译器”。
项目文件中的更改如下:
<ClCompile Include="Audio.cpp" />
- <ClCompile Include="Audio.h" />
+ <ClInclude Include="Audio.h" />