Using SFML to draw text from a function - c++

I'm trying to use a function to set a text to display on SFML based on the input parameters.
The function is of type Text and returns a text object. I've added cout statements to determine where the error is occurring. The text is as follows:
#include <string>
#include <iostream>
#include "functions.h"
using namespace std;
#include <SFML/Graphics.hpp> // include the SFML Graphics Library
using namespace sf;
Text showPoints(int& points, bool addPoints, bool isPlayer){
cout << "Function called " << endl;
string disPoints;
Text toDisp;
Font pointFont;
if(addPoints){
points += 1;
}
cout << "Points added" << endl;
if(!pointFont.loadFromFile("data/arial.ttf") ){
cout << "could not load font" << endl;
}
cout << "Loaded fonts" << endl;
if(isPlayer){
cout << "isPlayer conditional" << endl;
disPoints = "Player Points: ";
toDisp.setPosition(50, 800);
toDisp.setFont(pointFont);
toDisp.setString(disPoints);
toDisp.setFillColor(Color::White);
toDisp.setCharacterSize(30);
}
else if(!isPlayer){
cout << "isAI conditional" << endl;
disPoints = "AI Points: ";
toDisp.setPosition(1000, 200);
toDisp.setFont(pointFont);
toDisp.setString(disPoints);
toDisp.setFillColor(Color::White);
toDisp.setCharacterSize(30);
}
cout << "Conditions passed" << endl;
return toDisp;
}
//usual SFML stuff... under the while(window.isOpen()), before the
//window.display() and events check
cout << "Error on function?" << endl;
window.draw(showPoints(playerPoints, 0, 1));
cout << "First function passed" << endl;
window.draw(showPoints(AIPoints, 0, 0));
I expect that the text would show in the appropriate positions in the SFML window. However, the terminal outputs this and the window crashes:
Error on function?
Function called
Points added
Loaded fonts
isPlayer conditional
Conditions passed
Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
It must be a problem with the window.draw() function as the second draw function is not called. So is it legal to call a function of type Text in the window.draw()? If not, how should I go about this? Google searches yielded nothing helpful on this issue.

Related

Function pointer obtained from GetProcAddress crashes the program if it uses the stdlib

I'm trying to dynamically load a dll and call a function from it at runtime. I have succeeded in getting a working pointer with GetProcAddress, but the program crashes if the function from the dll uses the stdlib. Here's the code from the executable that loads the dll:
#include <iostream>
#include <windows.h>
typedef int (*myFunc_t)(int);
int main(void) {
using namespace std;
HINSTANCE dll = LoadLibrary("demo.dll");
if (!dll) {
cerr << "Could not load dll 'demo.dll'" << endl;
return 1;
}
myFunc_t myFunc = (myFunc_t) GetProcAddress(dll, "myFunc");
if (!myFunc) {
FreeLibrary(dll);
cerr << "Could not find function 'myFunc'" << endl;
return 1;
}
cout << "Successfully loaded myFunc!" << endl;
cout << myFunc(3) << endl;
cout << myFunc(7) << endl;
cout << myFunc(42) << endl;
cout << "Successfully called myFunc!" << endl;
FreeLibrary(dll);
return 0;
}
Here's code for the dll that actually works:
#include <iostream>
extern "C" {
__declspec(dllexport) int myFunc(int demo) {
//std::cout << "myFunc(" << demo << ")" << std::endl;
return demo * demo;
}
}
int main(void) {
return 0;
}
(Note that the main method in the dll code is just to appease the compiler)
If I uncomment the line with std::cout however, then the program crashes after the cout << "Sucessfully loaded myFunc!" << endl; line but before anything else gets printed. I know there must be some way to do what I want; what do I need to change for it to work?
As discussed in the comments, it turns out that the compiler's demands for a main function were hints that I was inadvertently making a an exe that decptively used the file extension dll, not an actual dll (because I didn't quite understand the compiler options I was using), which in some way messed up the dynamic loading of that assembly.

Multithreading with boost and opencv

I already wrote a program that detects different objects, and i'm now working on a tracking module to track the objects of interest. Because the detection isn't as fast, I'm hoping to pass in one frame with the detected objects about every 10-30 frames, and have the tracking module use camshift + kalman filtering to track the objects in the video stream until another new image with the detected objects is received from the detection module.
I'm pretty new to boost and c++ multi-threading in general and I wrote the following code just to see if I can be passing in frames from the detection module to the tracking module. For some reason, everything just freezes after the tracking module has received two imags. Any ideas why? Is there a better way to go about this? Thanks!
Main Thread (Detection module might work in a similar manner)
int main(int argc, char *argv[]){
cout << "main started" << endl;
Tracker tracker("Tracker");
tracker.start(imread("/home/cosyco/Desktop/images/lambo1.jpeg", CV_LOAD_IMAGE_COLOR));
boost::posix_time::seconds sleepTime(5);
cout << "main starting sleep" << endl;
boost::this_thread::sleep(sleepTime);
cout << "main just woke up, switching image" << endl;
tracker.resetImage(imread("/home/cosyco/Desktop/images/lambo2.jpeg", CV_LOAD_IMAGE_COLOR));
cout << "main sleeping second time" << endl;
boost::this_thread::sleep(sleepTime);
cout << "main just woke up, switching image" << endl;
tracker.resetImage(imread("/home/cosyco/Desktop/images/lambo3.jpeg", CV_LOAD_IMAGE_COLOR));
cout << "main sleeping third time" << endl;
boost::this_thread::sleep(sleepTime);
cout << "main just woke up, switching image" << endl;
tracker.resetImage(imread("/home/cosyco/Desktop/images/lambo4.jpeg", CV_LOAD_IMAGE_COLOR));
tracker.join();
cout << "main done" << endl;
return 0;
}
Tracker:
#include <iostream>
#include <boost/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
class Tracker{
private:
string name;
Mat trackerImage;
boost::thread trackerThread;
public:
Tracker (string newName){
cout << "creating tracker : " << newName << "created" << endl;
name = newName;
}
void track(Mat image){
image.copyTo(trackerImage);
informUpdate();
// use this new image to generate a histogram for camshift on the next
//few images in the video stream before a new image with the detected object is received
for (; ; ){
// cout << "tracking" << endl;
}
}
void start(Mat image){
cout << "in tracker's start" << endl;
// trackerThread = boost::thread(&Tracker::track, this, trackLimit);
trackerThread = boost::thread(&Tracker::track, this, image);
}
void join(){
trackerThread.join();
}
void resetImage(Mat image){
track(image);
}
void informUpdate(){
cout << "\033[1;31m image updated \033[0m" << endl;
}
};

Stop code execution on error (C++)

I have a library written in C++. The library has a function which accepts commands as a string and executes them. If an error is encountered (either in the command or while running the command) an "error function" is called which does some cleanup and finally calls exit(1). I am now trying to implement a graphical user interface (using Qt) to the library. The problem is that when an error is encountered, exit is called and my application crashes. I have access to the library source code but I would like to keep modifying the source code to minimum.
I am thinking of rewriting the error function such that it just stops executing code and stays in an idle state until another command is passed to the library from the user-interface. The problem is I am not sure how to go about doing it. I am basically looking for a function call equivalent to exit system call (so that the error function never returns to the code which generated the error) except that I do not want the application to exit but instead just go to an idle state and wait for calls from the user interface.
If there is another way to implement this please let me know. Please also let me know if you need more details.
Thanks in advance,
Here is some code which shows what my problem is
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
void error_func(string error);
void create_sphere(float radius);
void create_rect(float length, float width);
int main()
{
string command;
while(1) {
cout << "Enter command: ";
cin >> command;
if(command.compare("create_sphere") == 0) {
float radius;
cout << "Enter radius: ";
cin >> radius;
create_sphere(radius);
}
else if(command.compare("create_rect") == 0) {
float l, w;
cout << "Enter length and width: ";
cin >> l >> w;
create_rect(l, w);
}
else if(command.compare("quit") == 0)
break;
}
}
void create_sphere(float radius)
{
if(radius < 0)
error_func(string("Radius must be positive"));
cout << "Created sphere" << endl;
}
void create_rect(float length, float width)
{
if(length < 0)
error_func(string("Length must be positive"));
if(width < 0)
error_func(string("Width must be positive"));
cout << "Created rectangle" << endl;
}
void error_func(string error)
{
// do some cleanup
cout << "ERROR: " << error << endl;
exit(1);
}
Assume that create_sphere, create_rect and error_func are provided by the library. I can modify error_func as required but not the other functions (since there are many such functions).
Now when an error is encountered, I would like to go back to the while loop in main so that I can keep accepting other commands.
I am basically looking for a function call equivalent to exit system call (so that the error function never returns to the code which generated the error) except that I do not want the application to exit but instead just go to an idle state and wait for calls from the user interface.
Basically, you are looking for an event loop. The typical minimal Qt program is as follows:
#include <QApplication>
#include <QMainWindow>
int main(int argc, char **argv)
{
QApplication(argc, argv);
QMainWindow w;
w.show();
return application.exec(); // What you want instead of exit
}
Now, you could replace QMainWindow with your own class, and declare a slot in that which gets called when you are trying to handle a command from the user interface.
#include <QWidget>
...
class MyWidget : public QWidget
{
Q_OBJECT
public:
explicit MyWidget(QWidget *parent) : QWidget(parent)
{
connect(sender, SIGNAL(mySignal()), SLOT(handleCommand()));
}
public slots:
void handleCommand()
{
// Handle your command here.
// Print the error code.
qDebug() << error_func(string("Radius must be positive"));
// or simply:
qDebug() << "Radius must be positive";
} // Leaving the scope, and getting back to the event loop
}
As for the bogus library, well, if it exits, it does. There is not much you can do about that without fixint the library. It is a very bad behavior from most of the libraries.
The modification would be not to exit, but return an error code - which is a general practice in Qt software - and leave it with the application when to exit if they wish.
The application would not quit in your case. Again, It is a very bad idea for a library function to exit. Even Qt does not do except 1-2 times in a few million LOC.
I would suggest not to throw an exception. It is generally not common in Qt software, and you could make your software consistent by just using error codes like the rest of Qt does for you.
Invent an error state (idle state) and make the function never fail. The error state should become visible and be resolvable by some means.
If you can not reach a resolvable error state, it might be possible to rollback to some prior (initial) state.
If the options above are not possible you have some serious failure (software, hardware, data) and you might terminate the program.
All above can be achieved with return values or a getter function (indicating the current state) and a setter manipulating the current state - an exit call is a poor solution in a library. If you have an unresolvable state or can not rollback to a prior state you might throw an exception, catch it in the user interface and terminate the program after displaying the issue.
You should install a message handler which will automatically reduce a lot of your work.
Additionally it will help in reducing your debugging too. Here is my message handler for my Qt5 application. It will need a little tweaking if you are using Qt4:
QFile *logFile = NULL;//The file in which you will output the debug info to
QTextStream *logStream = NULL;//text stream for your log file
QMutex *mutex = NULL;//Always use mutex if you are multi threading your application
bool *debugMode = NULL;//it just a flag in case you want to turn off debugging
bool errorMsg = false;//use the value of this variable after QApplication::exec() if you need to show an error message
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
if(((logFile != NULL) && (debugMode != NULL)))
{
mutex->lock();
switch (type)
{
case QtDebugMsg:
if(!*debugMode)
{
mutex->unlock();
return;
}
*logStream << msg;
logStream->flush();
break;
case QtWarningMsg:
if(!((QString)context.function).contains("setGeometry"))
{
*logStream << "\n*** Warning ***\n";
*logStream << msg << endl;
*logStream << "Category: " << context.category << endl;
*logStream << "File: " << context.file << endl;
*logStream << "Function: " << context.function << endl;
*logStream << "Line: " << context.line << endl;
*logStream << "Version: " << context.version;
*logStream << "\n*** Warning Complete ***\n";
logStream->flush();
errorMsg = true;
SessionManager::get_obj()->saveCurrentSession();
}
break;
case QtCriticalMsg:
*logStream << "\n*** Critical ***\n";
*logStream << msg << endl;
*logStream << "Category: " << context.category << endl;
*logStream << "File: " << context.file << endl;
*logStream << "Function: " << context.function << endl;
*logStream << "Line: " << context.line << endl;
*logStream << "Version: " << context.version;
*logStream << "\n*** Critical Complete ***\n";
logStream->flush();
errorMsg = true;
SessionManager::get_obj()->saveCurrentSession();
break;
case QtFatalMsg:
*logStream << "\n*** Fatal ***\n";
*logStream << msg << endl;
*logStream << "Category: " << context.category << endl;
*logStream << "File: " << context.file << endl;
*logStream << "Function: " << context.function << endl;
*logStream << "Line: " << context.line << endl;
*logStream << "Version: " << context.version;
*logStream << "\n*** Fatal Complete ***\n";
logStream->flush();
errorMsg = false;
SessionManager::get_obj()->saveCurrentSession();
ShowErrorMsg(SessionManager::getSessionName());
exit(0);
}
mutex->unlock();
}
}
To install a message handler add the following code in the main() of your GUI.
qInstallMessageHandler(myMessageOutput);
You can ignore the check for setGeometry if you want to but I find that this warning is emitted unnecessarily. So you can keep it.
Also you may want to have a Session Manager which will automatically save the current session whenever an error is encountered.
When you have done this, you can safely call qFatal() when you want to terminate your application, or else use qCritical() if you want some other functionality.

boost removing managed_shared_memory when process is attached

I have 2 processes, process 1 creates a boost managed_shared_memory segment and process 2 opens this segment. Process 1 is then restarted and the start of process 1 has the following,
struct vshm_remove
{
vshm_remove()
{
boost::interprocess::shared_memory_object::remove("VMySharedMemory");
}
~vshm_remove()
{
boost::interprocess::shared_memory_object::remove("VMySharedMemory");
}
} vremover;
I understand that when process 1 starts or ends the remove method will be called on my shared memory but shouldnt it only remove it if Process 2 is not attached to it? I am attaching to the shared memory in process 2 using the following,
boost::interprocess::managed_shared_memory *vfsegment;
vfsegment = new boost::interprocess::managed_shared_memory(boost::interprocess::open_only, "VMySharedMemory");
I am noticing that the shared memory is removed regardless of Process 2 being connected.
I don't believe that there is any mention in the documentation that shared_memory_object::remove will fail if a process is attached.
Please see this section for reference: Removing shared memory. Particularly:
This function can fail if the shared memory objects does not exist or it's opened by another process.
This means that a call to shared_memory_object::remove("foo") will attempt to remove shared memory named "foo" no matter what.
The implementation of that function (source here) reflects that behavior:
inline bool shared_memory_object::remove(const char *filename)
{
try{
//Make sure a temporary path is created for shared memory
std::string shmfile;
ipcdetail::tmp_filename(filename, shmfile);
return ipcdetail::delete_file(shmfile.c_str());
}
catch(...){
return false;
}
}
In my experience with released production code, I've had success not calling shared_memory_object::remove until I no longer need access to the shared memory.
I wrote a very simple example main program that you might find helpful. It will attach to, create, or remove shared memory depending on how you run it. After compiling, try the following steps:
Run with c to create the shared memory (1.0K by default) and insert dummy data
Run with o to open ("attach to") the shared memory and read dummy data (reading will happen in a loop every 10 seconds by default)
In a separate session, run with r to remove the shared memory
Run again with o to try to open. Notice that this will (almost certainly) fail because the shared memory was (again, almost certainly) removed during the previous step
Feel free to kill the process from the second step
As to why step 2 above continues to be able to access the data after a call to shared_memory_object::remove, please see Constructing Managed Shared Memory. Specifically:
When we open a managed shared memory
A shared memory object is opened.
The whole shared memory object is mapped in the process' address space.
Mostly likely, because the shared memory object is mapped into the process' address space, the shared memory file itself is no longer directly needed.
I realize that this is a rather contrived example, but I thought something more concrete might be helpful.
#include <cctype> // tolower()
#include <iostream>
#include <string>
#include <unistd.h> // sleep()
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
int main(int argc, char *argv[])
{
using std::cerr; using std::cout; using std::endl;
using namespace boost::interprocess;
if (argc == 1) {
cout << "usage: " << argv[0] << " <command>\n 'c' create\n 'r' remove\n 'a' attach" << endl;
return 0;
}
const char * shm_name = "shared_memory_segment";
const char * data_name = "the_answer_to_everything";
switch (tolower(argv[1][0])) {
case 'c':
if (shared_memory_object::remove(shm_name)) { cout << "removed: " << shm_name << endl; }
managed_shared_memory(create_only, shm_name, 1024).construct<int>(data_name)(42);
cout << "created: " << shm_name << "\nadded int \"" << data_name << "\": " << 42 << endl;
break;
case 'r':
cout << (shared_memory_object::remove(shm_name) ? "removed: " : "failed to remove: " ) << shm_name << endl;
break;
case 'a':
{
managed_shared_memory segment(open_only, shm_name);
while (true) {
std::pair<int *, std::size_t> data = segment.find<int>( data_name );
if (!data.first || data.second == 0) {
cerr << "Allocation " << data_name << " either not found or empty" << endl;
break;
}
cout << "opened: " << shm_name << " (" << segment.get_segment_manager()->get_size()
<< " bytes)\nretrieved int \"" << data_name << "\": " << *data.first << endl;
sleep(10);
}
}
break;
default:
cerr << "unknown command" << endl;
break;
}
return 0;
}
One additional interesting thing - add one more case:
case 'w':
{
managed_shared_memory segment(open_only, shm_name);
std::pair<int *, std::size_t> data = segment.find<int>( data_name );
if (!data.first || data.second == 0) {
cerr << "Allocation " << data_name << " either not found or empty" << endl;
break;
}
*data.first = 17;
cout << "opened: " << shm_name << " (" << segment.get_segment_manager()->get_size()
<< " bytes)\nretrieved int \"" << data_name << "\": " << *data.first << endl;
}
break;
The aditional option 'w' causes that the memory be attached and written '17' instead ("the most random random number"). With this you can do the following:
Console 1: Do 'c', then 'a'. Reports the memory created with value 42.
Console 2: Do 'w'. On Console1 you'll see that the number is changed.
Console 2: Do 'r'. The memory is successfully removed, Console 1 still prints 17.
Console 2: Do 'c'. It will report memory as created with value 42.
Console 2: Do 'a'. You'll see 42, Console 1 still prints 17.
This confirms - as long as it works the same way on all platforms, but boost declares that it does - that you can use this way to send memory blocks from one process to another, while the "producer" only needs confirmation that the "consumer" attached the block so that "producer" can now remove it. The consumer also doesn't have to detach previous block before attaching the next one.

How to read and write input file and output file

I am trying to run the following program:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream inFile;
ofstream outFile;
double first=1.49, second=2.59, third=3.69, fourth=4.79;
inFile.open("prices.txt");
char response;
if(!inFile.fail())
{
cout << "A file by the name prices.txt exists.\n" << "Do you want to continue and overwrite it\n" << " with the new data (y or n);"; cin >> response;
if(tolower(response) == 'n')
{
cout << "The existing file will not be overwritten." << endl;
return -1;
}
}
outFile.open("prices.txt");
if (inFile.fail())
{
cout << "\n The file does not exist and can not be opened" << endl;
cout << "The file has been successfully opened for output." << endl;
outFile << first << "\n" << second << "\n" << fourth << "\n" << endl;
outFile.close();
exit(1);
cout << "The file has been successfully opened for output. " << endl;
outFile << first << "\n" << second << "\n" << third << "\n" << fourth << endl;
outFile.close();
return 0;
}
}
Yet this program will not write the values to the prices.txt file. If you run the program once it says the file does not exist. Running it a second time says the file is already there and if you want to overwrite it. The thing is searching my Mac I cannot find this file anywhere.
Any ideas what I am doing wrong with running it in Xcode? A friend runs the exact same code in Visual Studio 2008 and it works. Any help is appreciated.
You need to set the working directory for the executable since you are assuming that your data files are in the current working directory. In Xcode 3.x you set this in the first tab of Get Info for the executable. In Xcode 4.x it has been moved, but the principle is the same.
Alternatively you can change your data file paths (e.g. make them absolute) so that you do not make assumptions about the current working directory.
You may not have permission to write into the directory that you are trying to save the file too.
Also, there is an error in your program and I am sure if it is there for debugging reasons. You have
outFile.close();
exit(1);
But then shortly there after you try to write to the file, then close it again.