Executable using images in different directory - c++

I have the following directory structure
(root)
/ | \
bin resources src
| | |
Debug dot.bmp .cpp
|
.exe
I would like the .exe file to use dot.bmp.
Here's the code from the .cpp file that loads dot.bmp
player_img = il->load_image( "dot.bmp" );
I feel like I need to modify this line of code, but after changing it to:
player_img = il->load_image( "../resources/dot.bmp" );
I still get an error saying that the image couldn't be loaded.
What do I need to change? Is this even possible, or should I just give up and put the image in the same directory as the .exe?

You need to go down one further level in order to get to the root.
../../resources/dot.bmp
Your executable is in bin/Debug but I think you coded under the assumption that it is in bin.
Assuming you are on Windows, the relative path will be relative to the current working directory rather than the directory where the executable resides. Often they are the same thing, but not necessarily.
I would be inclined to use fully-qualified paths and pre-pend the directory where the executable lives. You can obtain this by calling GetModuleFileName passing NULL as the hModule argument. This will return the full path to the executable so you will need to strip off the file name portion.
You will also need to think about deployment. This structure looks like your development structure but you may want a different organisation when you deploy the program. For example, I'd expect the executable to live in the bin directory when deployed.
One final thought. Assuming the images that your program needs is known at compile time it would be much easier to link them into the executable as resources. That way you simply don't have to worry about these issues at all and the executable can stand alone.

Related

How to use Instruments Time Profiler with Executable

I'm trying to use Mac Instruments Time Profiler to optimize my code for building a MandelBox. I found how to make my executable my target process, but when the program runs, it gives me an error in the Console window saying it cannot find the .txt file associated with the program.
Do I need to tell the profiler where to look to find the file? The text file is already in the same directory as the executable. Any thoughts? Thanks.
This problem is not unique to Instruments. The same thing would presumably happen if your current working directory was something other than the location of your program. For example, if you were to do cd / ; /path/to/yourprogram.
You either need to make your program find its own location and then find its text file as a sibling in the containing directory or take the path of the text file as an argument. Or, you will always have to set the working directory to your program's location before invoking it.
That last approach is an immediate workaround for the problem with Instruments. On the panel where you choose the target executable, you can also configure various parameters, such as arguments, environment variables, and the working directory. Set the working directory to the directory that contains the text file and it should work.

Where would incorrectly named files (rename without specifying the path) be moved to?

I accidentally made a big blunder:
In my C++ program, I did:
std::string oldFilePath = "/Users/blah/somepath/foo.xml";
std::string newFileName = "foo.xml" //Blunder! Forgot to prefix the new path!
int status = rename(oldFilePath.c_str(), newFileName.c_str());
I forgot to prefix the new path, and just put the filename (without a path) for the new name that the file should be renamed to. As a result the file has vanished from the old path, and I don't know where its gone to!
Where is the file ? Is there a way to recover it ? (Time Machine is disabled for this folder, so I can't do that!)
EDIT: Where would the compiled file generated by Xcode for a C++ application be ?
EDIT: If you're running the program through xcode, it should be in:
~/Library/Developer/Xcode/DerivedData//Build/Products/Debug/
Don't forget the ~ in the above path!
If the operation succeeded (status == 0), the file would be in the current directory of the process when it was run. It is hard to predict where that might be, but $HOME is one plausible candidate (maybe /Users/blah/foo.xml). You should be able to find it, either with the find command or with Spotlight.
I don't use the XCode UI (or other IDEs), in part because I don't like the lack of control over things like 'where the program is put' and 'what is the current directory when I run the program' (and for the rest because I'm a dinosaur). AFAIK, the executable should be in a directory underneath the folder where you created the project. Again, Spotlight or find should be able to help you, at least if you chose a distinctive name for the program. The project directory is another place to look for the foo.xml file too.

Files being created in the wrong folder

To give a little context: I'm writing a program that uses text files and BMP files. For the text files I was provided with a class to manage them and I'm using EasyBMP for the BMP manipulation.
The problem I have is the files are being created in the wrong folder unless I provide the full path.
Example:
#include "EasyBMP.h"
int main(){
BMP picture;
picture.SetSize(640,480);
picture.WriteToFile("picture.BMP");
return 0;
}
Expected result: 640x480 BMP file created somewhere in my project folder (C:\Users[user]\Documents\C++\TP 1)
Actual result: 640x480 BMP file created in Eclipse folder (C:\Users[user]\Documents\Eclipse)
The same happens with any other file I write to disk.
It used to work fine on a different project so I'm guessing there's something silly I'm missing somewhere but I haven't been able to find a solution.
EDIT: The exact same code works fine on a different project.
If you don't specify a full pathname, files are stored in the process's current folder. You can change that in Eclipse (tell if which folder to run from when you run the process).
If you always want the files to be stored where your EXE is, or somewhere around the EXE, you can find the folder yourself(the first argument to main is the location of the EXE file).
The program will write the file in the working directory. That's because you used a relative path and relative paths are relative to the working directory.
Either specify a full path in your code, or ensure that the working directory is set to your desired value when running the program.

Relative Path Using imread (OpenCV)

i have a problem of which i am not sure where it comes from. Please take a look at this function:
http://pastie.org/8200205
imread appears to return empty matrices.
To be clear, my images are in the directory ImageData which is directly where my program lies, and for each object type like apple, i have a directory that is called like the object type and inside are all the apple images (if that's the current object type)
Additionally, i'm working with cmake but i'm pretty sure that i don't have to include directories w/o any code.
So what's the problem here? Is my pathing wrong or does imread not work in subdirectories?
I appreciate any suggestions/solutions :)
Relative paths are relative to the process working directory. This is not necessarily the same as the directory in which the executable resides. So assuming you've got everything else right, then the most likely explanation is that your working directory is not the same as the directory in which the executable resides.
In any case, it sounds as though you want the program to locate the files in a directory relative to the executable. In which case you should not rely on the working directory and instead you will need to form the full path to the files. You'll just need to prepend the directory of the executable.

how to write path of external file in an included c++ source

Suppose I'm writing a library or a set of tools mytool where a class MyTool that other people can use is defined. Suppose I have a directory tree like this:
project
| - program1
| - main1.cpp
...
| - mytool
| - mytool.h
| - mytool.cpp
| - data.txt
in tool1.cpp I use the external binary huge file data.dat:
ifsteam f("data.txt");
the main1.cpp use mytool, but if mytool.(s)o is linked with main1.o the program can't find data.dat, for this case I need to change the previous line to:
ifstream f("../mytool/data.txt");
but I can't know where other people put mytool for example they can have a different directory tree:
project
| - program1
| - main1.cpp
| - mytool
| - tool1.h
| - tool2.cpp
| - data.dat
In addition (am I right?) the path depend on where the program is executed.
The only solution I can imagine is to pass to the class contructor MyTool the path of data.dat but I want to keep hidden this file for the user.
You need to know the absolute path of the file, or else the path of the file relative to your working directory. One approach is to have a configuration script which the user runs before compiling your program. The script then hardcodes into your program the relevant path, so the program has the path hardwired in a manner customized for the user.
Sometimes that's not an option because you don't want to distribute the source code, or because you wish to allow the path to change at runtime. Then you can read a configuration file at runtime which says where the file is. But this is just a layer of abstraction: you still need to know where that configuration file is. You might, for example, ask the system where the user's personal directory is, and then find the file there at that directory. This is a sort of mix between compile-time and runtime computation of the path.
One option would be to use an environment variable for the location of your tools. For instance, name it MYTOOLDIR. You can set the path on installation of MyTool. A call to getenv("MYTOOLDIR"); can resolve the path.
On windows, within the mytool dir, run SETX PATH=%PATH%;./, or on Linux, just PATH=$PATH:./. (Provide a set_env.bat or whatnot to do it.)
You'll need to make the location of the binary file a configuration value that the user defines on a particular installation of the program. Or, more easily, just always put the binary file in the same place as the final executable and use "data.dat" as the path.