Creating a CUSTOM exe file in C++ - c++

I'm working on a simple game engine just for the experience of it. I've realized, though, that I have no idea how to export the user's custom game as its own standalone executable. For example (this is not my actual game engine, it just provides an easy reference for discussion), suppose we had the following very simple code:
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
void RunGame(string question, string answer)
{
string submission;
cout << question << endl;
getline(cin, submission);
if (submission == answer)
cout << "Correct!";
else
cout << "Wrong!";
}
int main()
{
string question;
string answer;
cout << "Enter Question:" << endl;
getline(cin, question);
cout << "Enter Answer:" << endl;
getline(cin, answer);
RunGame(question, answer);
}
In this example the user gets to create their own customized bit of trivia, and then can test it immediately afterwards when RunGame is called. Now I want to be able to save their game with the trivia information they provided as its own .exe (basically it will perform from the call to RunGame onwards). How would I go about doing that?
To be clear, this isn't a question about what is the easiest/fastest way to make a game. It is looking for how to build a standalone, executable file from within code.

If you really want to store data inside the .exe itself:
An executable has a header that defines its size, boundaries and other useful stuff to the Operating System, so, essentially, the operating system knows where the code and data sections start and end, and it finally uses this information to load up the .exe to memory when it is asked to run.
Since the Operating System knows (besides the .exe's file size) where the executable actually ends, this also means that any data pasted after the .exe's "calculated" end (by headers) won't negatively effect the binary. It will still load and execute just fine.
You can abuse this property to concatenate data after the end of the executable.
I'll leave you with this test, using Windows' bundled WordPad application as a 'host' for some other data:
Go to C:\Windows and copy write.exe (WordPad) to another folder, so we can experiment without damaging anything.
Bring to that folder another file, any file will do. In my example, the data file will be a PDF called "myfancyfile.pdf"
Now, open a command prompt and use the COPY command to stitch both files together, making sure the .exe comes first:
copy /B write.exe+myfancyfile.pdf mynewprogram.exe
copy's /B flag means "binary copy", so essentially both files were pasted together without any kind of text or data conversion.
Try to run "mynewprogram.exe". Realize it runs just fine :-)
Self-modifying your .exe with data is not only feasible, it won't negatively effect functionality. Having that said, it is still a ugly way to persist data.
Have fun coding your solution.

You don't want to do this. A better way is to save the trivia in some custom format (for example, .txt, .dat, ..).
Then the game just handles this data.
So first think about the format inside of the .txt for example.
Lets say at first theres a number, indicating which entry this is. Second follows the question and after that the answer follows. This, you must decide for yourself.
Example trivia-data.txt
1
How old is actor X from show Y?
32 years
2
...
...
#include <iostream> // std::cout, std::endl
#include <fstream> // std::ifstream, std::ofstream
using namespace std;
int main()
{
// create file
ofstream ofile("trivia-data.txt");
// define your data
int num_of_question = 1;
string question, answer;
getline(cin, question);
getline(cin, answer);
// write your data to the file
ofile << num_of_question << '\n';
ofile << question << '\n';
ofile << answer << '\n';
// close the file
ofile.close();
return 0;
}
Now that you created your data you just have to build your program in a way you would like to present this. Instead of writing to a file, you should read from a file and print the questions out and compare answers and what not. Look up std::ifstream for reading your file.
At the start you could ask your user if he would like to create a quiz or play one that already exists.
Edit:
Since this sounds a lot like homework I just provide some pseudo code.
I'd go for an approach like this(pseudo code):
print "Would you like to create(c) or play(p) a quiz? Answer(c/p): "
input = get_input() // 'c' or 'p'
if input == 'c'
// now do what I posted with some loops to create a couple of questions
else
print "Please provide an URL to the quiz-data you would like to play: "
url = get_input() // C:/test.txt
// read in data, print out questions, do comparisons and print answers etc
This is infinitely easier than your approach and this also makes it possible for others to create quizzes not just you.

Building an executable is non-trivial. You will first need to comply with the target operating systems' ABI so that it can find your program's entry point. The next step will be deciding how your program is going to be able to access system resources: probably you'll want your executable to implement dynamic linking so it can access shared libraries, and you'll need to load the various .dll or .so files you're going to need. All the instructions you'll need to write for this will vary from OS to OS, you may need to introduce logic to detect the exact platform and make informed decisions, and you will need to vary for 32 vs 64 bit.
At this point you're about ready to start emitting the machine instructions for your game.
A reasonable alternative here is (as done by Unity) to provide a "blank" executable with your engine. Your engine itself would be a shared library (.dll or .so) and the blank executable would simply be a wrapper that loads the shared library and invokes a function in it with a pointer to something in it's data section.
Generating your user's executable would comprise loading the appropriate blank, making platform-specific modifications to it to tell it the size of the data section you're intended to provide it with and writing your data in the appropriate format. Or, you could simply have a blank that has an embedded copy of the raw structure into which you write values, just like populating a struct in memory:
struct GameDefinition {
constexpr size_t AuthorNameLen = 80;
char author_[AutherNameLen+1];
constexpr size_t PublisherNameLen = 80;
char publisher_[PublisherNameLen+1];
constexpr size_t GameNameLen = 80;
char name_[GameNameLen+1];
constexpr size_t QuestionLen = 80;
constexpr size_t AnswerLen = 80;
char question_[QuestionLen+1];
char answer_[AnswerLen+1];
};
static GameDefinition gameDef;
#include "engine_library.h" // for run_engine
int main() {
run_engine(&gameDef);
}
You'd compile this againsst the shared-library stub for your engine, and emit it as an executable, then you'd look up the platform-specific details of the executable format, locate the position of "gameDef" in it. The you'd read the blank into memory, and write it out with the definition of "gameDef" replaced with the one based on user input.
But what many engines do is simply ship or require the user to install a compiler (Unity relies on C#). So instead of having to tweak executables and do all this crazy platform-specific stuff, they simply output a C/C++ program and compile it.
// game-generator
bool make_game(std::string filename, std::string q, std::string a) {
std::ostream cpp(filename + ".cpp");
if (!cpp.is_open()) {
std::cerr << "open failed\n";
return false;
}
cpp << "#include <engine.h>\n";
cpp << "Gamedef gd(\"" << gameName << "\", \"" << authorName << \");\n";
cpp << "int main() {\n";
cpp << " gd.q = \"" << q << \"\n";
cpp << " gd.a = \"" << a << \"\n";
cpp << " RunGame(gd);\n";
cpp << "}\n";
cpp.close();
if (!invoke_compiler(filename, ".cpp")) {
std::cerr << "compile failed\n";
return false;
}
if (!invoke_linker(filename)) {
std::cerr << "link failed\n";
return false;
}
}
If "RunGame" is not part of your engine but user-supplied, then you could emit that as part of the cpp code. Otherwise, the intent here is that it's making a call into your library.
Under Linux you might compile this with
g++ -Wall -O3 -o ${filename}.o ${filename}.cpp
and then
g++ -Wall -O3 -o ${filename} ${filename}.o -lengine_library
to link it against your engine's library.

Related

Reading files when spawning a child process when the current directory is not the executable directory

Edit 1: This is NOT a duplicate of this question because that person wants to know how to get the executable path. I can get the path just fine, I'm just wondering if there's a more convenient way of USING the path without modifying hundreds of calls to ifstream in my code.
Edit 2: First I'm moving Edit #1 to the top because people still think that the other question answers mine. It does not. I am NOT asking that question. Also I'm going to clarify that my initial question was probably phrased incorrectly. Someone posted in the comments a solution that works for me.
Here is how I would rephrase my question.
I have a program which spawns child processes, in other words it's a program that runs other programs. Program A spawns B, C, D, E, F, etc. My files are organized like so: Program A is at "dir/a/" and B is at "dir/a/b/" and C is at "dir/a/c/" etc.
Now assuming that Program B is written in C++ and it uses ifstream to deal with reading and writing files, my initial question was "is there a way to write Program B's code so that it can deal with reading in files from the executable directory and not from the directory it was spawned?" Because when A runs B, B thinks it's in "dir/a/" when the file is in "dir/a/b/file.txt". So calling ifstream("file.txt") goes to the wrong place. I would need to rewrite the code to ifstream(prefix + "file.txt") everywhere in Program B's code instead. This also needs to work such that I can run B directly rather than through A. Other programs like C, D, E, F, etc. may or may not be written in C++ and may or may not have implemented their own ways of handling this problem.
Many of the solutions posted are just different ways of doing the prefix + filename trick which I already knew about before I asked this question.
The solution posted below that I found which worked is to just change the directory before spawning the process. Thus when the process is spawned, it thinks it is in the new directory. This solves my problem because now it will work for any program, whether it is B, C, D, E, etc or whether it is in C++ or uses ifstream at all. This should have been really obvious in hindsight but for some reason I didn't realize I could run a command to change the directory before spawning the process. So this works for my case and so that's why it's the answer to my question.
Other people keep writing answers to the wrong question, though maybe that's my fault for not writing in the right way or understanding what my problem really was in the first place.
-- The original post --
I have two programs. Program A spawns the child process Program B. Program B uses std::ifstream("file.txt") to read in a file. However, Program A is located in /programs/a/ while Program B is in /programs/a/children/b/. Meaning that when I spawn B as a child process, Program B thinks its current directory is /programs/a and looks for file.txt there (but file.txt is actually in /programs/a/children/b).
I know that the first argument passed to Program B is always the executable path, so I can just take that and modify my calls to file I/O functions to prefix the path with that. But how do I do this in a good way? Is there a convenient way to get this to work without changing much code in Program B? I want to be able to run Program B on its own, as well as from Program A, and in both cases it should be able to read file.txt. That's why I can't just hardcode the filepath, I want it to work in both cases without changing any code between them.
For instance, I can think of making a wrapper class and then changing every call of std::ifstream so that it calls the wrapper instead, kind of like this:
std::ifstream Wrapper::ifstream(const std::string& path)
{
return std::ifstream(prefix + path); // prefix is member variable
}
But for a project with many calls to ifstream this is inconvenient and possibly inconsistent. Any accidental use of ifstream directly could cause a crash. I would also need to do the same thing for any output filestreams too. And I would really like to minimize any external dependencies, so I'd prefer if there was a built-in way to avoid this problem. It would be nice if I could just toggle some kind of option in the ifstream class so that any call to ifstream("file.txt") becomes ifstream("path/to/file.txt"). Is this the best I can do, or is there any better option out there?
There is a standard (since C++17) way to figure this out. It is important to notice that as this is standard, it should work with every platform where C++ is implemented: Windows, Linux, MacOS, etc. The standard will take care of handling idiosyncrasies as separators.
You can use std::filesystem::canonical to get the current executable's location. Then get the location of the parent directory and append the filename you want.
An example is:
namespace fs = std::filesystem;
int main( int argc, char* argv[] ) {
fs::path path( fs::canonical( argv[0] ) );
fs::path file = path.parent_path() / "file.txt";
std::cout << file << std::endl;
}
This should print /programs/a/children/b/file.txt on Linux or Mac and "c:\Programs\A\Children\b\file.txt" on Windows (if paths are like that).
Here is an illustration of using an environment variable as a common information that any program started from a shell in which it is defined can use. The writer writes a short text to a file, the reader reads it out. Both programs try to read the environment variable A_B_PROG_FILE which should contain the path to a file (which may not exist). This variable name is hard-coded common information; if we had the opportunity to use a common header (but not a duplicated one!) we could as well communicate the path itself that way; this is something to consider. But let's assume that the programs do not share a build environment.
First the writer.cpp:
#include <iostream>
#include <fstream>
#include <cstdlib>
/** #return -1 if file could not be opened, -2 if a write error occurred,
or 0 on success
*/
int main(int argc, char **argv)
{
const char *envPath = std::getenv("A_B_PROG_FILE");
const char *fpath = envPath ? envPath : "/tmp/defaultname.txt";
std::ofstream f(fpath);
if(!f)
{
std::cerr << "Couldn't open " << fpath << " for writing, exiting\n";
return -1;
}
f << "Hello, file ->" << fpath << "<- here!\n"
<< "This was written by ->" << (argc? argv[0] : "Unknown exe path") << "<-\n";
return f ? 0 : -2; // if f is not good exit with error code.
}
The reader is very similar:
#include <iostream>
#include <fstream>
#include <cstdlib> // getenv()
/** #return -1 if file could not be opened, -2 if a read error occurred,
or 0 on success
*/
int main()
{
const char *envPath = std::getenv("A_B_PROG_FILE");
const char *fpath = envPath ? envPath : "/tmp/defaultname.txt";
std::ifstream f(fpath);
if(!f)
{
std::cerr << "Couldn't open " << fpath << " for reading, exiting\n";
return -1;
}
std::cout << "file ->" << fpath << "<- contains: ->";
char c;
while(f.get(c))
{
std::cout << c;
}
std::cout << "<-";
if(!f.eof())
{
std::cerr << "Read error from ->" << fpath << "<-, exiting\n";
return -2;
}
}
Here is a sample session:
$ ls /tmp
$ unset A_B_PROG_FILE
$ ./reader
Couldn't open /tmp/defaultname.txt for reading, exiting
$ ./writer
$ ./reader
file ->/tmp/defaultname.txt<- contains: ->Hello, file ->/tmp/defaultname.txt<- here!
This was written by ->./writer<-
<-
$ export A_B_PROG_FILE=/tmp/ab
$ ./reader
Couldn't open /tmp/ab for reading, exiting
$ ./writer
$ ./reader
file ->/tmp/ab<- contains: ->Hello, file ->/tmp/ab<- here!
This was written by ->./writer<-
<-
$

Making a variable that has code inside of it?

Is there a way I can make a variable in C++ that has code inside of it that I can run later?
For example:
string code = "cout << "Hello World" << endl;"?
Or make a file or Notepad file that can be run later? Like if someone adds an employee to a program, it'll make a file and add all of the employee's information. Then later on when the program user says "I want to see that employee" by either writing their name or a unique ID, it shows all of the employee's information.
Thank you.
The solution is to use #define preprocessor directive to create a macro:-
#define code cout << "Hello World" << endl;
Now whereever you use the word 'code', it will be replaced by cout << "Hello World" << endl;
eg:
int main()
{
code
return 0;
}
Yes, it's relatively new syntax.
std::string msg = "Hello world";
auto code = [&std::cout, =msg]() {std::cout << msg;};
// Now we can pass code about as a variable.
code(); // runs it, even if std::cout and msg has gone out of scope
The advantage is that a comparison function, or a key access function, or similar can be attached to a bigger structure. You can also build entire programs out of lambdas, but that's getting rather theoretical.
However you must specify the C++ code at compile time. You can't compile C++ on the fly (yet).

Is it possible to load/read shape_predictor_68_face_landmarks.dat at compile time?

I am trying to build a C++ application in Visual Studio using DLIB's face_landmark_detection_ex.cpp. The build application run from command promt and trained model and image file is passed as arguments.
face_landmark_detection_ex.exe shape_predictor_68_face_landmarks.dat image.jpg
this shape_predictor_68_face_landmarks.dat is the trained model for 68 landmarks to perform detection on input image and needs to load at run-time every time to perform any detection. I am trying to do following things.
Load this shape_predictor_68_face_landmarks.dat at building the application or compile time.
Read this shape_predictor_68_face_landmarks.dat inside the code so that every time my application strarts its execution, it will not take more amount of memory.
Is there any way to pack this file inside my application so that it will take less physical memory to run.
Update:
How can I store this shape_predictor_68_face_landmarks.dat file in a static buffer so that every time shape_predictor can read from this buffer.
Yes, its possible, but depends on Visual Studio and not cross-platform
You should create resource file and include hape_predictor_68_face_landmarks.dat into your project. See https://msdn.microsoft.com/ru-ru/library/7zxb70x7.aspx for details. This will make compiler to put this file into your exe/dll
Open resoure at runtime and get memory pointer https://msdn.microsoft.com/en-us/library/windows/desktop/ee719660(v=vs.85).aspx
Create memory stream (std::istream) from pointer.
deserialize from this stream with dlib::deserialize
Here is minimal example, but without resource reading:
#include <string>
#include <iostream>
#include <dlib/image_processing/shape_predictor.h>
struct membuf : std::streambuf {
membuf(char const* base, size_t size) {
char* p(const_cast<char*>(base));
this->setg(p, p, p + size);
}
};
struct imemstream : virtual membuf, std::istream {
imemstream(char const* base, size_t size)
: membuf(base, size)
, std::istream(static_cast<std::streambuf*>(this)) {
}
};
using namespace dlib; //its important to use namespace dlib for deserialize work correctly
using namespace std;
int main(int argc, const char* argv[])
{
const char* file_name = "shape_predictor_68_face_landmarks.dat";
ifstream fs(file_name, ios::binary | ios::ate);
streamsize size = fs.tellg();
fs.seekg(0, ios::beg);
std::vector<char> buffer(size);
if (fs.read(buffer.data(), size))
{
cout << "Successfully read " << size << " bytes from " << file_name << " into buffer" << endl;
imemstream stream(&buffer.front(), size); // here we are loading from memory buffer. you can change this line to use pointer from Resource
shape_predictor sp;
deserialize(sp, stream);
cout << "Deserialized shape_predictor" << endl;
}
else cout << "Failed to read " << file_name << " into buffer" << endl;
return 0;
}
And about memory usage.
First of all you should know that shape_predictor::operator() is const, and the documentation says that is safe to use one shape_predictor for different threads.
So, you can create one shape_predictor at the start of program and use it many times, even from different threads
Next, putting shape predictor inside resource will make it be loaded into RAM when program starts, but deserializing it from resource will make copy of this memory, and this will lead to RAM usage overhead. If you need minimal possible RAM usage - you should load it from file
And the last your question - how to initialize it by compiler. There is no ready-to-use solution for it, but you can use the code from shape_predictor.h/deserialize function and load it manually. I think, this is bad solution, because you will not get less RAM usage compared to loading file
So my recommendation is to load one shape_predictor from file and use it globally for all threads
I know this is an old question, but a Visual Studio only solution would not have worked in my case since I am using dlib in Linux/macOS. Here is a Unix compatible solution that I came up with.
What I did was to use the xxd tool to convert the model file into the unsigned char [] representation of the file contents, write that into a custom header file, and use that inside deserialize (rather than read in the file during execution).
The following command would generate the header file for shape_predictor_68_face_landmarks.dat:
xxd -i shape_predictor_68_face_landmarks.dat > shape_predictor_68_face_landmarks.hpp
If you look inside shape_predictor_68_face_landmarks.hpp, there will be 2 variables: shape_predictor_68_face_landmarks_dat of type unsigned char [] containing the contents of the model file and shape_predictor_68_face_landmarks_dat_len of type unsigned int.
Inside your dlib driver code, you would do the following
...
#include "shape_predictor_68_face_landmarks.hpp"
...
shape_predictor sp;
std::stringstream landmarksstream;
landmarksstream.write((const char*)shape_predictor_68_face_landmarks_dat, shape_predictor_68_face_landmarks_dat_len);
deserialize(sp, landmarksstream);
A word of warning: be careful about opening files generated by xxd because they can be quite large and cause your text editor to crash.
I can't answer to the efficiency of this method, but it does allow for the model file to be "read in" at compile time rather than execution time.

C++: Retrieving filename from istream

I have a function:
void read_file(istream &file);
In main(), I would pass in something like:
ifstream file;
file.open(argv[1]);
read_file(file);
Now, inside the read_file function, is there a way to get name of the file passed in?
For example, if argv[1] was "data1.txt", can we extract that string from inside read_file?
Thanks in advance.
By the way, I've tried:
cout << file << endl; // Doesn't work.
cout << &file << endl; // Same result.
They print an address.
File streams don't provide any way of retrieving the file name (or the open mode for that matter). What you can do is store it in the stream's cache using pword() and xalloc(). You would also need to register the necessary callbacks to resolve lifetime dependencies.
You could store the file name in a class level variable within main() so that it would be available for output within your read_file function:
const char* inFile = ""; // input file
int main(int argc, char* argv[])
{
// assign value from args to
// class level variable 'inFile'
inFile = argv[1];
}
Then you could output 'inFile' within your read_file function:
cout << inFile << endl;
The kind of thing you are asking for is normally done at the operating system level. That tends not to be portable and does not make it into standard libraries.
For example, supposed you opened the file with
"~/../something.txt"
What should the library return as the file name?
What if you opened a symbolic link?
What if the operating system permits multiple file names through directories for the same file?
The amount that the operating system can fill in depends upon the system itself. For example, if you've ever worked on a VMS system, it's system services do a lot of filling in that Unix and Dos systems do not.
Library designers avoid these system dependent problems by not including these features.

Multiplatform way to determine if a dynamic library is present

I need to check if a dynamic library is present, so that later I can safely call functions that use this library.
Is there a multiplatform way to check this? I am targeting MS Windows 7 (VC++11) and Linux (g++).
To dynamically "use" a function from a shared library requires that the library isn't part of the executable file, so you will need to write code to load the library and then use the function. There may well be ways to to do that in a portable fashion, but I'm not aware of any code available to do that.
It isn't very hard code to write. As "steps", it involves the following:
Load the library given a name of a file (e.g. "xx", which is then translated to "xx.so" or "xx.dll" in the architecture specific code).
Find a function based on either index ("function number 1") or name ("function blah"), and return the address.
Repeat step 2 for all relevant functions.
When no longer needing the library, close it with the handle provided.
If step 1 fails, then your library isn't present (or otherwise "not going to work"), so you can't call functions in it...
Clearly, there are many ways to design an interface to provide this type of functionality, and exactly how you go about that would depend on what your actual problem setting is.
Edit:
To clarify the difference between using a DLL directly, and using one using dynamic loading from the code:
Imagine that this is our "shared.h", which defines the functions for the shared library
(There is probably some declspec(...) or exportsymbol or other such stuff in a real header, but I'll completely ignore that for now).
int func1();
char *func2(int x);
In a piece of code that directly uses the DLL, you'd just do:
#include <shared.h>
int main()
{
int x = func1();
char *str = func2(42);
cout << "x=" << x << " str=" << str << endl;
return 0;
}
Pretty straight forward, right?
When we use a shared library that is dynamically loaded by the code, it gets a fair bit more complex:
#include <shared.h>
typedef int (*ptrfunc1)();
typedef char * (*ptrfunc2)(int x);
int main()
{
SOMETYPE handle = loadlibrary("shared");
if (handle == ERROR_INDICATOR)
{
cerr << "Error: Couldn't load shared library 'shared'";
return 1;
}
ptrfunc1 pf1 = reinterpret_cast<ptrfunc1>(findfunc("func1"));
ptrfunc2 pf2 = reinterpret_cast<ptrfunc2>(findfunc("func2"));
int x = pf1();
char *str = pf2(42);
cout << "x=" << x << " str=" << str << endl;
return 0;
}
As you can see, the code suddenly got a lot more "messy". Never mind what hoops you have to jump through to find the constructor for a QObject, or worse, inherit from a QObject. In other words, if you are using Qt in your code, you are probably stuck with linking directly to "qt.lib" and your application WILL crash if a Qt environment isn't installed on the machine.
LoadLibrary calls should fail, then you can know if the dynamic library is present or not. Also with dynamic loading you get the function pointer from the dynamic library and if the pointer is null then the platform doesn't support that function on that platform.
On windows you have LoadLibrary API to load a dynamic lib. And GetProcAddress API to look up the desired function in that lib. If GetProcAddress returns NULL for that particular function that you are looking for that functionality is not present for that platform. You can log then and decide fallback.