Bonjour !
Je suis en plein apprentissage de la SFML grâce au livre qui lui est dédié, mais je rencontre un problème après avoir terminé le deuxième chapitre. En effet, je n'arrive pas à compiler le code donné sur github(
https://github.com/SFML/SFML-Game-Development-Book/tree/master/02_Resources).
L'erreur est :
1>main.obj : error LNK2001: symbole externe non résolu "public: class sf::Texture & __thiscall ResourceHolder<class sf::Texture,enum Textures::ID>::get(enum Textures::ID)" (?get@?$ResourceHolder@VTexture@sf@@W4ID@Textures@@@@QAEAAVTexture@sf@@W4ID@Textures@@@Z)
1>main.obj : error LNK2001: symbole externe non résolu "public: void __thiscall ResourceHolder<class sf::Texture,enum Textures::ID>::load(enum Textures::ID,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?load@?$ResourceHolder@VTexture@sf@@W4ID@Textures@@@@QAEXW4ID@Textures@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
1>C:\...\Projects\SFML-Chap2\Release\Projet2.exe : fatal error LNK1120: 2 externes non résolus
========== Génération : 0 a réussi, 1 a échoué, 0 mis à jour, 0 a été ignoré ==========
Après recherche sur le net, il semblerait que mon compilateur considère que les fonctions "ResourceHolder::load(Identifier id, const std::string& filename)" et "ResourceHolder<Resource, Identifier>::get(Identifier id)" soient déclarées, mais non implémentées.. Or, elles le sont bel et bien dans mon code source.
Voici mes trois fichiers, à savoir ResourceHolder.h, ResourceHolder.cpp et le main.cpp (la seule différence avec ceux sur github sont les #includes ) :
ResourceHolder.h
#ifndef BOOK_RESOURCEHOLDER_HPP
#define BOOK_RESOURCEHOLDER_HPP
#include <map>
#include <string>
#include <memory>
#include <stdexcept>
#include <cassert>
template <typename Resource, typename Identifier>
class ResourceHolder
{
public:
void load(Identifier id, const std::string& filename);
template <typename Parameter>
void load(Identifier id, const std::string& filename, const Parameter& secondParam);
Resource& get(Identifier id);
const Resource& get(Identifier id) const;
private:
void insertResource(Identifier id, std::unique_ptr<Resource> resource);
private:
std::map<Identifier, std::unique_ptr<Resource>> mResourceMap;
};
#endif // BOOK_RESOURCEHOLDER_HPP
ResourceHolder.cpp
#include "ResourceHolder.h"
template <typename Resource, typename Identifier>
void ResourceHolder<Resource, Identifier>::load(Identifier id, const std::string& filename)
{
// Create and load resource
std::unique_ptr<Resource> resource(new Resource());
if (!resource->loadFromFile(filename))
throw std::runtime_error("ResourceHolder::load - Failed to load " + filename);
// If loading successful, insert resource to map
insertResource(id, std::move(resource));
}
template <typename Resource, typename Identifier>
template <typename Parameter>
void ResourceHolder<Resource, Identifier>::load(Identifier id, const std::string& filename, const Parameter& secondParam)
{
// Create and load resource
std::unique_ptr<Resource> resource(new Resource());
if (!resource->loadFromFile(filename, secondParam))
throw std::runtime_error("ResourceHolder::load - Failed to load " + filename);
// If loading successful, insert resource to map
insertResource(id, std::move(resource));
}
template <typename Resource, typename Identifier>
Resource& ResourceHolder<Resource, Identifier>::get(Identifier id)
{
auto found = mResourceMap.find(id);
assert(found != mResourceMap.end());
return *found->second;
}
template <typename Resource, typename Identifier>
const Resource& ResourceHolder<Resource, Identifier>::get(Identifier id) const
{
auto found = mResourceMap.find(id);
assert(found != mResourceMap.end());
return *found->second;
}
template <typename Resource, typename Identifier>
void ResourceHolder<Resource, Identifier>::insertResource(Identifier id, std::unique_ptr<Resource> resource)
{
// Insert and check success
auto inserted = mResourceMap.insert(std::make_pair(id, std::move(resource)));
assert(inserted.second);
}
main.cpp
#include <SFML/Graphics.hpp>
#include <iostream>
#include "ResourceHolder.h"
// Resource ID for sf::Texture
namespace Textures
{
enum ID
{
Landscape,
Airplane,
};
}
int main()
{
sf::RenderWindow window(sf::VideoMode(640, 480), "Resources");
window.setFramerateLimit(20);
// Try to load resources
ResourceHolder<sf::Texture, Textures::ID> textures;
try
{
textures.load(Textures::Landscape, "../Media/Image/Desert.png");
textures.load(Textures::Airplane, "../Media/Image/Eagle.png");
}
catch (std::runtime_error& e)
{
std::cout << "Exception: " << e.what() << std::endl;
return 1;
}
// Access resources
sf::Sprite landscape(textures.get(Textures::Landscape));
sf::Sprite airplane(textures.get(Textures::Airplane));
airplane.setPosition(200.f, 200.f);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::KeyPressed || event.type == sf::Event::Closed)
return 0;
}
window.clear();
window.draw(landscape);
window.draw(airplane);
window.display();
}
}
J'utilise Visual Studio Professional 2012 et tout fonctionnait parfaitement pour le chapitre 1. Alors, si quelqu'un pouvait m'aider, je lui en serais très reconnaissant !
Merci,