Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: SFML Game Development Book - Chapitre 2 - Error LNK2001 [RÉSOLU]  (Lu 2301 fois)

0 Membres et 1 Invité sur ce sujet

jonatansan

  • Newbie
  • *
  • Messages: 2
    • Voir le profil
    • E-mail
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.  :o

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,
« Modifié: Juin 01, 2014, 02:48:15 am par jonatansan »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : SFML Game Development Book - Chapitre 2 - Error LNK2001 ?
« Réponse #1 le: Avril 29, 2014, 08:55:14 pm »
Si tu compilais le code qui se trouve au bout du lien que tu donnes, ça fonctionnerait. Ton code est différent, et c'est cette différence qui provoque l'erreur.
Laurent Gomila - SFML developer

PtichapronRouge

  • Newbie
  • *
  • Messages: 41
    • Voir le profil
    • E-mail
Re : SFML Game Development Book - Chapitre 2 - Error LNK2001 ?
« Réponse #2 le: Mai 01, 2014, 12:10:35 pm »
Le livre explique que tes fonctions templates doivent etre implementées dans un fichier .inl et non pas dans un fichier .cpp. De plus, tu ne dois pas inclure le header dans le .inl mais le .inl dans le header.
En gros ton header est de cette forme :

#ifndef RESOURCEHOLDER_HPP
#define RESOURCEHOLDER_HPP
<template<typename T, typename P>
class ResourceHolder
{
//attributs et methodes*
};

#include "ResourceHolder.inl"

#endif // ResourceHolder.hpp
 
« Modifié: Mai 01, 2014, 12:12:23 pm par PtichapronRouge »
Un coca, un ordinateur, et un livre SFML Game Development. Elle est pas belle la vie ?

PtichapronRouge

  • Newbie
  • *
  • Messages: 41
    • Voir le profil
    • E-mail
Re : SFML Game Development Book - Chapitre 2 - Error LNK2001 ?
« Réponse #3 le: Mai 01, 2014, 12:11:52 pm »
Et dans le .inl contenant les implementations, tu ne mets pas
#include "ResourceHolder.hpp
ou le compilo t'insulteras ;)
« Modifié: Mai 11, 2014, 12:04:27 am par PtichapronRouge »
Un coca, un ordinateur, et un livre SFML Game Development. Elle est pas belle la vie ?

jonatansan

  • Newbie
  • *
  • Messages: 2
    • Voir le profil
    • E-mail
Re : SFML Game Development Book - Chapitre 2 - Error LNK2001 ?
« Réponse #4 le: Mai 05, 2014, 08:39:24 pm »
D'accord, merci pour les réponses !  :)

J'ai effectué les modifications et ai obtenu une tonne d'erreurs de compilation, mais il se trouve que la solution était ici : http://stackoverflow.com/questions/17876510/visual-studio-wont-compile-template-class-with-inl-implementation (Je partage, si jamais quelqu'un d'autres à le même type de problème que moi)