Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Library built upon SFML won't return texture pointer correctly  (Read 5301 times)

0 Members and 1 Guest are viewing this topic.

Moonkis

  • Jr. Member
  • **
  • Posts: 58
    • View Profile
Quick backstory:
I'm collecting useful classes inside my own library called Vildhjarta that is dependent on SFML, it's dynamic ( .dll ) and links statically towards SFML when compiled.

Problem
Inside Vildhjarta there is a class called "Graphics" that loads and returns texture files and caches them inside a map.

Problem is when using Graphics::getTexture() ( loads texture if not found in cache ) it returns a valid pointer but It doesn't display when trying to draw it.

I can however access it, getting information such as size.

Minimal Recreation
Tricky but here is the main.cpp:
#include <SFML\Graphics.hpp>
#include <Vildhjarta\Graphics.hpp>
#include <iostream>

int main(int argc, char **argv)
{
        sf::RenderWindow window(sf::VideoMode(600,400,32), "@Window" );
        sf::Event event;
       
        vh::Graphics g;
        sf::Texture* t = new sf::Texture();
        std::cout << t->getSize().x << " " << t->getSize().y << std::endl;
        delete t;
    t = g.getTexture("victorsplash.png");
        std::cout << t->getSize().x << " " << t->getSize().y << std::endl;
       
       
        sf::Sprite s;
        s.setTexture((*t));
        while( window.isOpen() )
        {
                while( window.pollEvent(event))
                {
                       
                }
                window.clear(sf::Color::Black);
                window.draw(s);
                window.display();
        }
               
        return 0;
}
 

Here is Graphic.hpp inside Vildhjarta.dll :
#ifndef _WELLSPRING_GRAPHICS_HPP
#define _WELLSPRING_GRAPHICS_HPP

#include <SFML\Graphics.hpp>
//#include "ResourceCache.hpp"
#include <string>
#include <map>
namespace vh
{
        class Graphics
        {
        public:
                sf::Texture* getTexture(std::string gfx);
                void removeTexture(std::string gfx);
                void loadTexture(std::string gfx);
        private:
                //vh::ResourceCache<sf::Texture> m_cache;
                std::map<std::string, sf::Texture*> m_cache;
        };
}



#endif
 

And here is the implementation ( stripped from everything else ):
/* Includers and stuff */
sf::Texture* vh::Graphics::getTexture(std::string gfx)
{
        sf::Texture* texture = nullptr;
        if( m_cache.find(gfx) != m_cache.end())
                texture = m_cache[gfx];
               
        if( texture == nullptr )
        {
                texture = new sf::Texture();
                if( !texture->loadFromFile(gfx) )
                {
                        std::cout << "Graphics couldnt load file " << gfx << std::endl;
                        delete texture;
                        return nullptr;
                }
                std::cout << "Graphics loaded file " << gfx << " correctly" << std::endl;
                m_cache[gfx] = texture;
        }
        std::cout << "Returned texutre pointer" << std::endl;
        return m_cache[gfx];
}
 

Additional information
The above code will output 0,0 and then after calling graphics-getTexture("victorsplash.png") it will output 600,400 which is the dimension of the image that is loaded, but setting the sprite to it will still not draw it.

If I include the raw files i.e the headers and .cpp files to my project it works fine, loading and drawing.

Both the project and the library project links statically towards SFML

I have no clue on how to solve this, I'v been trying like crazy.

« Last Edit: April 04, 2013, 11:31:37 am by Moonkis »

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Library built upon SFML won't return texture pointer correctly
« Reply #1 on: April 04, 2013, 11:35:25 am »
Your code is a real mess. Don't use manual memory management, it's very unclear who owns what and how long each object lives. Instead, use RAII and store your dynamically allocated objects inside std::unique_ptr.

And read a bit more about std::map. If you use find(), you can directly take the returned iterator to access the element, you don't need to search with operator[] again.

If you follow the tips, your code will already be much more readable, and it's much likelier to see the error ;)
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Moonkis

  • Jr. Member
  • **
  • Posts: 58
    • View Profile
Re: Library built upon SFML won't return texture pointer correctly
« Reply #2 on: April 04, 2013, 12:07:51 pm »
I like manual memory management, besides if you have the whole context you will understand that Graphics.hpp owns the resources.

I will apply the map-tip though.

A bit more on topic:

Trying something like this results in the same problem, basically returning a pointer will cause my error.
sf::Texture* vh::Graphics::getTexture(std::string gfx)
{
        sf::Texture* t = new sf::Texture();
        if( !t->loadFromFile(gfx) )
        {
                delete t;
                std::cout << "Couldn't load file" << std::endl;
                return nullptr;
        }
        return t;
}
 

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Library built upon SFML won't return texture pointer correctly
« Reply #3 on: April 04, 2013, 12:15:44 pm »
I like manual memory management
Please read the RAII thread I linked, especially this post. It's not a matter of taste, it's a matter of code robustness, maintainability and safety. Manual memory management introduces so many problems you can easily avoid with RAII. Don't just ignore them.

Trying something like this results in the same problem, basically returning a pointer will cause my error.
I'm sure the pointer itself is not the problem. Can you come up with a complete and minimal example? Are you sure the loading succeeds?
« Last Edit: April 04, 2013, 12:17:41 pm by Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Moonkis

  • Jr. Member
  • **
  • Posts: 58
    • View Profile
Re: Library built upon SFML won't return texture pointer correctly
« Reply #4 on: April 04, 2013, 12:18:54 pm »
Trying something like this results in the same problem, basically returning a pointer will cause my error.
I'm sure the pointer itself is not the problem. Can you come up with a complete and minimal example? Are you sure the loading succeeds?
I could try to reduce it but it's pretty close to minimum.

Moonkis

  • Jr. Member
  • **
  • Posts: 58
    • View Profile
Re: Library built upon SFML won't return texture pointer correctly
« Reply #5 on: April 04, 2013, 12:40:42 pm »
Here is an minimal ( minimal ) example
Main.cpp:
#include <stdio.h>

#include <SFML\Graphics.hpp>
#include <Jalle\Graphics.hpp>

int main(int argc, char **argv)
{
        sf::RenderWindow window;
        window.create(sf::VideoMode(600,400,32), "Window");
        sf::Event event;
        sf::Sprite sprite;
        sf::Texture* texture = loadAndReturn("victorsplash.png");
        sprite.setTexture(*texture);
        while( window.isOpen() )
        {
                while( window.pollEvent(event) )
                {
                       
                }
                window.clear(sf::Color::Black);
                window.draw(sprite);
                window.display();
        }
        delete texture;
        return 0;
}
 

Jalle\Graphics.hpp:
#ifndef _GRAPHICS_HPP
#define _GRAPHICS_HPP

#include <SFML\Graphics.hpp>
#include <string>

sf::Texture* loadAndReturn(std::string file);

#endif
 

and Jalle\Graphics.cpp:
#include "Graphics.hpp"
#include <cstdio>

sf::Texture* loadAndReturn(std::string file)
{
        sf::Texture* texture = new sf::Texture();
        if( texture->loadFromFile(file) == false )
        {
                std::printf("Couldn't load file");
                delete texture;
                return nullptr;
        }
        return texture;
}
 

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Library built upon SFML won't return texture pointer correctly
« Reply #6 on: April 04, 2013, 12:59:25 pm »
That's not minimal. Read the link I gave you.

Also try other variants, like using a direct pointer instead of a function. Show the smallest possible code that still reproduces your problem, and show a single file that is self-contained, so that we can be sure there are no other issues in your code.
« Last Edit: April 04, 2013, 01:03:31 pm by Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10835
    • View Profile
    • development blog
    • Email
Re: Library built upon SFML won't return texture pointer correctly
« Reply #7 on: April 04, 2013, 01:03:18 pm »
That's not minimal. Read the link I gave you.
I think the problem here is, that one part needs to be build as library, he at least stated:
If I include the raw files i.e the headers and .cpp files to my project it works fine, loading and drawing.

So I'm guessing it could be a problem between static vs dynamic linking. It's usually never a good idea to mix those (except maybe C vs C++ libraries). So have you tried linking SFML & your lib dynamically or both statically?
Do you have a build script at hand, to create the library? I don't feel like writing one, but I'd gladly test things if there was one. :)

Btw. you should never use \ for paths, it should always be /. Windows doesn't have a problem with forward slashes. ;)
« Last Edit: April 04, 2013, 01:05:17 pm by eXpl0it3r »
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Library built upon SFML won't return texture pointer correctly
« Reply #8 on: April 04, 2013, 01:05:59 pm »
From a DLL, you have to export symbols, otherwise you get linker errors in the final application. Are you sure you build a dynamic library?

How does the executable link SFML?
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10835
    • View Profile
    • development blog
    • Email
Re: Library built upon SFML won't return texture pointer correctly
« Reply #9 on: April 04, 2013, 01:23:16 pm »
Also:
Main.cpp
#include <stdio.h>

#include <SFML\Graphics.hpp>
#include <Jalle\Graphics.hpp>
 

Jalle\Graphics.hpp:
#include <SFML\Graphics.hpp>
#include <string>
 

Does that mean you're also linking against SFML in the application itself?
Static linking SFML won't make any sense then...
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Moonkis

  • Jr. Member
  • **
  • Posts: 58
    • View Profile
Re: Library built upon SFML won't return texture pointer correctly
« Reply #10 on: April 04, 2013, 02:22:45 pm »
That's not minimal. Read the link I gave you.

Also try other variants, like using a direct pointer instead of a function. Show the smallest possible code that still reproduces your problem, and show a single file that is self-contained, so that we can be sure there are no other issues in your code.

I'm sorry Nexus I should have been clearer in my opening post about the problem. Thank you for your help though and I'll check out map a bit more ( FYI, I am using RAII as much as possible, though I haven't made the move onto smart pointers yet. ).

That's not minimal. Read the link I gave you.
I think the problem here is, that one part needs to be build as library, he at least stated:
If I include the raw files i.e the headers and .cpp files to my project it works fine, loading and drawing.

So I'm guessing it could be a problem between static vs dynamic linking. It's usually never a good idea to mix those (except maybe C vs C++ libraries). So have you tried linking SFML & your lib dynamically or both statically?
Do you have a build script at hand, to create the library? I don't feel like writing one, but I'd gladly test things if there was one. :)

Btw. you should never use \ for paths, it should always be /. Windows doesn't have a problem with forward slashes. ;)

I was linking the executable statically towards SFML and dynamically towards my own library ( that linked statically towards SFML.... ).

I tried both statically and both dynamical and it worked flawlessly! Lesson learned, don't link libraries that have dependencies on each other differently.

Also:
Main.cpp
#include <stdio.h>

#include <SFML\Graphics.hpp>
#include <Jalle\Graphics.hpp>
 

Jalle\Graphics.hpp:
#include <SFML\Graphics.hpp>
#include <string>
 

Does that mean you're also linking against SFML in the application itself?
Static linking SFML won't make any sense then...
Yes, I am ( or was ) linking statically towards SFML when compiling the library as well as when compiling the executable.

It made sense at the time xD
But if I don't link statically toward SFML when compiling the library I couldn't link towards it dynamically while linking towards SFML statically when building my application ...