SFML community forums

Help => System => Topic started by: ZenLeopard on April 07, 2014, 12:21:38 pm

Title: sf::InputStream unresolved external symbol
Post by: ZenLeopard on April 07, 2014, 12:21:38 pm
Hey everyone,

If I try to use my "Resource" class that's just based on sf::InputStream I do always get a bunch of compiler errors like:

- error LNK2001: unresolved external symbol "public: virtual __int64 __thiscall engine::Resource::tell(void)" (?tell@Resource@engine@@UAE_JXZ)
- error LNK2001: unresolved external symbol "public: virtual __int64 __thiscall engine::Resource::getSize(void)" (?getSize@Resource@engine@@UAE_JXZ)
- error LNK2001: unresolved external symbol "public: bool __thiscall engine::Resource::open(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?open@Resource@engine@@QAE_NV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)


I'm using Visual Studio 2012 for Desktop and I'm using the 32bits version of SFML. Everything works fine, excepting the resource loading.

The preprocessor definition "SFML_STATIC" is set and I've linked the static libraries of SFML (sfml-audio-s.lib, sfml-graphics-s.lib, sfml-window-s.lib, sfml-network-s.lib, sfml-system-s.lib and sfml-main.lib).

I've just followed this tutorial: http://www.sfml-dev.org/documentation/2.1/classsf_1_1InputStream.php

And that's how my class looks like:

class Resource : public sf::InputStream
{
        public:
                Resource(std::string archive);
        public:
                bool open(std::string file);
        public:
                sf::Int64 read(void* data, sf::Int64 size);
        public:
                sf::Int64 seek(sf::Int64 position);
        public:
                sf::Int64 tell();
        public:
                sf::Int64 getSize();
};

And that's how I use it:

Resource assets("Assets.era");
// ...
Image icon(assets, "Icon.png");
// ...
window.setIcon(32, 32, icon);

Thanks for any help.

Regards
Title: Re: sf::InputStream unresolved external symbol
Post by: Laurent on April 07, 2014, 12:31:08 pm
The errors mean that some functions of the Resource class have no definition (you forgot to implement them).
Title: Re: sf::InputStream unresolved external symbol
Post by: ZenLeopard on April 07, 2014, 07:54:07 pm
I see, thanks for the quick response.
Sure that the smallest mistakes are causing the biggest problems.
Title: Re: sf::InputStream unresolved external symbol
Post by: ChronicRat on April 16, 2014, 04:44:12 pm
Are you just from Java? No need to place public each line. Place once and to the next keyword - all members will be public. =)
Title: Re: sf::InputStream unresolved external symbol
Post by: ZenLeopard on April 16, 2014, 05:30:41 pm
Hell no, I know that I could do it that way, it's just my style.
Over the years of using C++ I felt better to write an accessor for each member.
Nothing would take me to Java ("Compile once - debug everywhere...") =)
Title: Re: sf::InputStream unresolved external symbol
Post by: Rosme on April 16, 2014, 07:03:36 pm
I'd really like to know what you like in that? I mean, it's hardly readable. What don't you like in something like this:
class Foo {
public:
        struct Bar {
                int a;
                int b;
        };

public:
        Foo();
        ~Foo();

        void something();
        void somethingElse(const Bar& bar);

protected:
        int mA;
        int mB;
        int mC;

private:
        int mD;
        int mE;
        int mF;
};
Title: Re: sf::InputStream unresolved external symbol
Post by: ZenLeopard on April 16, 2014, 07:33:42 pm
After all it looks better, indeed.

class Assets
{
        protected:
                std::string folder;
        public:
                Assets(std::string path);
                void setFolderPath(std::string path);
                std::deque<char> getBinaryMetaData();
                std::string append(std::string content);
                operator std::string &();
                operator int &();
                // ...
};
 

As compared to:

class Assets
{
        protected:
                std::string folder;
        public:
                Assets(std::string path);
        public:
                void setFolderPath(std::string path);
        public:
                std::deque<char> getBinaryMetaData();
        public:
                std::string append(std::string content);
        public:
                operator std::string &();
        public:
                operator int &();
        // ...
};
 

But I've never noticed drawbacks (excepting the additional lines of code).
Title: Re: sf::InputStream unresolved external symbol
Post by: Jesper Juhl on April 16, 2014, 07:43:32 pm
The drawback /is/ the additional (redundant) lines of code.
The compiler doesn't care, but human readers do.
Putting "public:" before each line is unneeded and messy and makes the code hard to read since it is contrary to most (all?) common styles.
Title: Re: sf::InputStream unresolved external symbol
Post by: ZenLeopard on April 16, 2014, 08:22:36 pm
Quote
After all it looks better, indeed.

Quote
Putting "public:" before each line is unneeded and messy and makes the code hard to read since it is contrary to most (all?) common styles.

I'll switch over to that style in the future. Will be fun in several lines of XAudio2 and OpenGL code.
Title: Re: sf::InputStream unresolved external symbol
Post by: Nexus on April 16, 2014, 11:34:53 pm
What I am doing for example is having another access specifier between different blocks of declarations, even if it's strictly speaking redundant. "Different blocks" means public types, public methods, private methods, private variables.

This helps separate them, and you can easily move a whole block if the declaration order requires it, without changing the semantics.