3
\$\begingroup\$

I am writing a resource manager for a hobby game project that reads textures/fonts etc.

Up to now, I was giving the location of the files relative to the executable path, like:

my_texture.loadFromFile("textures\\my_texture.png");

However, now I realized that the relative path I'm giving is relative to the working directory of the game. So, for example, if I run the executable from my IDE (which sets the working directory to the project directory instead of executable directory), the game fails to load the texture and crashes.

I was thinking about using the main's argv[0] and did some research on it, but apparently it is not reliable (it might just give the name of the exe).

So, how can I get the path to my resource files reliably? How does the professionals do it?

I'm using the SFML and C++17. I would like a portable solution if possible, otherwise Windows.

I checked this question but it wasn't helpful.

\$\endgroup\$
3
\$\begingroup\$

Give the resource management API an understanding of what the input paths are relative to. Depending on your underlying OS, there are a variety of ways to get the full path to the running executable, independent of working directory. On Windows, for example, one function you could use for this is GetModuleFileNameA.

Once you've got that full path and trimmed the executable name from it (if needed), you can store it someplace and append you relative resource paths to it every time you are about to load. This gives you an absolute path to the resource.

SFML may have a portable wrapper equivalent to GetModuleFileNameA, although I'm not sure what it is offhand and a very quick search through the API reference didn't reveal anything.

\$\endgroup\$
  • \$\begingroup\$ boost::filesystem::current_path(), or perhaps you could parse main's argv[0]. \$\endgroup\$ – Mark Storer May 8 at 12:17
  • 1
    \$\begingroup\$ Boost's a reasonable option. main's argv[0] isn't guaranteed to be in a form useful for this, although if it works on all the platforms one cares about, obviously, that's the simplest. The OP mentioned that one already though. \$\endgroup\$ – Josh May 8 at 13:21
  • \$\begingroup\$ @MarkStorer boost::filesystem::current_path() returns the current working directory, which might be often different from the executable's directory \$\endgroup\$ – Sweeney Todd May 8 at 15:48
  • \$\begingroup\$ Correct, and if main(argv[0]) is a relative path, you require the current one. Sorry I wasn't more explicit. \$\endgroup\$ – Mark Storer May 9 at 14:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.