Asked  7 Months ago    Answers:  5   Viewed   181 times

I know this question has been asked before but I still haven't seen a satisfactory answer, or a definitive "no, this cannot be done", so I'll ask again!

All I want to do is get the path to the currently running executable, either as an absolute path or relative to where the executable is invoked from, in a platform-independent fashion. I though boost::filesystem::initial_path was the answer to my troubles but that seems to only handle the 'platform-independent' part of the question - it still returns the path from which the application was invoked.

For a bit of background, this is a game using Ogre, which I'm trying to profile using Very Sleepy, which runs the target executable from its own directory, so of course on load the game finds no configuration files etc. and promptly crashes. I want to be able to pass it an absolute path to the configuration files, which I know will always live alongside the executable. The same goes for debugging in Visual Studio - I'd like to be able to run $(TargetPath) without having to set the working directory.

 Answers

24

There is no cross platform way that I know.

For Linux: readlink /proc/self/exe

Windows: GetModuleFileName

Tuesday, June 1, 2021
 
dotoree
answered 7 Months ago
55

Use source("yourfile.R", chdir = T)

Wednesday, June 2, 2021
 
qitch
answered 6 Months ago
79

Use URI Paths instead of "absolute" path, see this post

Uri path = Uri.parse("android.resource://com.segf4ult.test/" + R.drawable.icon);
Uri otherPath = Uri.parse("android.resource://com.segf4ult.test/drawable/icon");

Or use openRawResource(R.id) to open an inputStream, and use it the same way you would use a FileInputStream (readonly)

Wednesday, June 2, 2021
 
muaaz
answered 6 Months ago
41

As indicated, on modern compilers you will actually need to use Phoenix V3, as Phoenix V2 relies on the old result-of protocol, which in newer versions of boost libraries just isn't always included anymore.

Additionally on some compilers (AFAIK at least clang) the BOOST_RESULT_OF_USE_DECLTYPE approach is enabled by default, which may cause the supporting libraries to omit the (more costly) TR1 result-of protocol.

The good news is, after we signaled this on the user list as a recurring stumbling block, the official decision is here:

Farewell Phoenix-2 Dec 14, 2013; 3:38am (Joel de Guzman)
(also blog post)

Boost C++... After more than a decade, I finally retired Phoenix-2 from the Boost Spirit code base. I feel sad. It's like farewell to a good friend. Onwards to Phoenix-3.

That's just 7 days ago :)

So in the (near) future this problem will have been resolved.

Saturday, July 31, 2021
 
viky
answered 4 Months ago
14

Putting operator<< in std like Remus's answer is undefined behavior in the C++ 14 draft (N4296 section:17.6.4.2.1). Boost provides a hook (used by this answer) and you can write:

namespace boost
{
    namespace test_tools
    {
        template<typename T,typename U>
        struct print_log_value<std::pair<T, U> >
        {
            void operator()(std::ostream& os, std::pair<T, U> const& pr)
            {
                os << "<" << std::get<0>(pr) << "," << std::get<1>(pr) << ">";
            }
        };
    }
}

print_log_value is a template so if you are not declaring a templated value like pair<T,U>, you will need to write something like:

template<>
struct print_log_value<MyType>{ /* implementation here*/ };

Edit

If you are using boost 1.59 or later you need to use namespace boost::test_tools::tt_detail instead. That is, the code needs to start:

namespace boost
{
    namespace test_tools
    {
        namespace tt_detail
        {
Wednesday, August 11, 2021
 
Saurabh
answered 4 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share