Weird interaction: ECL throws errors on windows when TGUI tries to create an Edit Box - c++

I am currently using TGUI (a GUI library based on SFML) together with ECL (so I can use Lisp for config and scripts). It works fine on Linux/gcc, but on Windows/MinGW ECL throws an error:
Condition of type: FLOATING-POINT-INVALID-OPERATION
#<a FLOATING-POINT-INVALID-OPERATION>
Available restarts:
1. (CONTINUE) Ignore signal
Top level in: #<process TOP-LEVEL>.
>
The point in code at which the error is thrown (minimal code that creates it) is:
empty_panel = tgui::Panel::Ptr(*cur_gui, "empty_panel");
empty_panel->setSize(cfg.res.x, cfg.res.y);
empty_panel->setBackgroundColor(sf::Color::Transparent);
tgui::EditBox::Ptr txt_test(*empty_panel, "txt_test");
Note that I can create Labels, Buttons, Checkboxes, etc. just fine - but once I try to make an Edit Box, ECL complains.
This does not make any sense to me whatsoever. TGUI and ECL are completely unrelated libraries, not sharing functions or depending on each other in any way that I know of. Does anyone have an idea what might cause this behavior?
EDIT: Just did a complete recompile of SFML, TGUI and ECL with the most recent version of MinGW, and it still breaks in exactly the same way. So I've decided that enough is enough and I'll rewrite my project to use SFGUI instead.
From now on, this question is of academic interest only.

I finally found out what might have happened there:
While ECL is running, it tries to handle all uncaught exceptions, segfaults, etc that happen on it's watch, even if they never interact with LISP. And the way it handles them is by immediately jumping to the REPL when they occur, to allow for manual debugging.
Which is the sane thing to do for anything that happens because of errors in a LISP program or C/C++ functions that interact with it, but is mildly confusing when the error happens in unrelated C++ code (like the presumed bug in TGUI).
Minimal way to reproduce: Load ECL and try some invalid operation, like so:
#include <ecl/ecl.h>
int main(int argc, char **argv) {
cl_boot(argc, argv);
atexit(cl_shutdown);
int x = 1/0;
return EXIT_SUCCESS; }

Related

How to solve a function acting differently based on callsite?

Not sure how to word the title so feel free to rename, but the issue I'm having is that I've got a function that works in one project, but fails in another. Below is rough pseudocode to show that one call in LibraryProject works, whereas the call in GameProject doesn't.
In ChildClass::do_stuff, the win32_window HWND is valid, whereas the second one, failed_win32_window is null and glfw throws an error saying it isn't initialized, despite it already having been initialized (since the first glfw call was successful and I've manually stepped through to verify it was):
GLFWError #65537 Happen, The GLFW library is not initialized
Here's pseudocode showing the two projects, and the files. GLFW is set initialized properly since if I do all my glfw logic within LibraryProject, the window shows up as normal.
//LibraryProject
////library_header.h
class ParentClass {
GLFW* _mainWindow; //filled in elsewhere in the real code
HWND getWin32Window() { return glfwGetWin32Window(_mainWindow); }
}
//GameProject
////game_header.h
#include "library_header.h" //from other Project
class ChildClass : public ParentClass {
void do_stuff() {
HWND win32_window = this->getWin32Window(); //this works because it goes down into LibraryProject.dll's module
HWND failed_win32_window = glfwGetWin32Window(_mainWindow); //but literally the same call here doesn't because it happens within GameProject.exe
}
}
////game_body.cpp
void function_called_elsewhere_in_game() {
//called from GameProject.exe
auto child = ChildClass();
child.do_stuff();
}
I'm not sure if this is an issue with glfw and my setup, or just my misunderstanding how projects and dependencies work.
Things I've tried:
Downloading the latest glfw3
Rebuilding the entire solution
Toggling with References and Linking Dependency Inputs
Things to note:
This is happening in the main thread, nothing else is using glfw at the same time. Its 100% reproducible too.
glfw3.lib is always being created in my GameProject output folder, based on the one inside LibraryProject
Stepping through the disassembly for each of the two glfwGetWin32Window calls has different addresses in disassembly, leading me to believe they're two different copies of the same library, but I'm not sure.
This is not an issue with cocos2d, the game engine I'm using as starting a blank project and calling glfwGetWin32Window(..) returns a valid pointer, even in GameProject, so there's something that I'm doing wrong, but I don't know what.
Images showing off the actual behaviour. magnolia_cocos_proj is GameProject and is the exe I'm running, and libcocos2d is LibraryProject I'm using as a DLL (I'm unfamiliar with the details of how linking and dlls work).
win32_window has valid value
definition of getWin32Window() to be 100% sure. Notice the module is in libcocos2d.dll now.
after going over the second line, the error throws and the second window is null
As I understood from "glfw3.lib is always being created" you use static linking. Static linking of a lib to different dll and exe lead to duplicating of all static memory of the lib. You should use a dynamic library for GLFW in the case. It's glfw3dll.lib.
There are two main cases why this error could appear:
GLFWError #65537 Happen, The GLFW library is not initialised
Case One :
The mentioned error occurs if a GLFW function was called that mustn't be called unless the library is initialised. So, you need to initialise GLFW before calling any function that requires initialisation.
Read an API introduction for reference. Use if-else statement for handling glfwInit() and errors.
Reading Moving from GLFW 2 to 3 is also useful.
Case Two :
This error quite often occurs in the case you have previous versions of GLFW installed on your machine. GLFW3 doesn't like running along with previous version installed. So, delete all the GLFW libraries and linkers and reinstall the latest GLFW 3 from scratch.
Hope this helps.

Qt QDir::current()

I had some code like this:
void MainWindow::saveData()
{
QDir oldDir=QDir::current();//this should return the main executable directory.Since there is no other place in my hole code where i temper with QDir.
QDir sess("Sessions");
if(!oldDir.exists("Sessions"))//if "Sessions" Dir doesn't exist
oldDir.mkdir("Sessions");//create it.
QDir::setCurrent(sess.absolutePath());
//some virtual code inside current Dir, which i didn't implement yet.
QDir::setCurrent(oldDir.absolutePath());//restore old dir
}
When I run my app firstly the code works perfectly.but in the second run, the first call to QDir::current(); returns the "Sessions" Dir and not the main executable Dir as it should be restored in the first run.actually i did manage to overcome this by adding one line at the biginning of the code, the following :
QDir::setCurrent(QCoreApplication::applicationDirPath());
Still I want to know why the first code didn't work.already checked for the documentation of the functions and found nothing.
QDir::current();//this should return the main executable directory
No it should not! Not unless you change it to point there first.
I'm dead serious when I'll say this: Yours is a myth, fantasy, whatever you call it, I have no idea what gave you the idea. Point me to a spec that says so. Oh, you can't, because there's no such spec, no such requirement. It's someone's twilight hour mirage that seems to perpetuate itself endlessly. If you heard it from someone, you have every right to be angry at them this very moment, for they did you a big disservice.
Generally speaking, for applications that are not normally started from the command line, the initial working directory can be anything and it will be platform- and session/system configuration dependent. For a typical GUI application, assuming any particular initial working directory is a fool's errand and completely misguided.
Once you change it to where you want it to point to, you of course have full control over it, but the initial working directory must be assumed to be random and out of your control.
For example, on Windows I can start your application through an Explorer shortcut where I can specify whatever startup folder I desire, and you have zero control over it. On OS X, Finder sets the working directory to something or another, IIRC to the folder where the app bundle resides. Again, you as a developer have no control over it unless there's some setting in the bundle that you could add to that effect, but that is platform-specific and will be ignored if your application is not started through Finder or bundle API mechanisms (they probably are called something else). And so on. It's completely arbitrary and it's pointless to depend on its initial value.
If you want to refer to the application's installation directory or executable directory, do so explicitly. Do not assume anything about the initial working directory of a GUI application.
I tried with the below code and it works fine for several runs.
The version details of Qt and OS may help.
Qt creator 3.3.2 (open source). Qt lib 5.4.1.Os windows 8.1
#include <QCoreApplication>
#include "QDir"
#include "qDebug"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QDir oldDir=QDir::current();
qDebug()<<QDir::current().absolutePath();
QDir sess("H:\\cuteapps\\session");
if(!oldDir.exists("H:\\cuteapps\\session"))//if "Sessions" Dir doesn't exist
oldDir.mkdir("H:\\cuteapps\\session");//create it.
QDir::setCurrent(sess.absolutePath());
qDebug()<<QDir::current().absolutePath();
return a.exec();
}
output 1:
"H:/cuteapps/build-untitled2-Desktop_Qt_5_4_1_MSVC2012_OpenGL_32bit-Debug"
"H:/cuteapps/session"
output 2:
"H:/cuteapps/build-untitled2-Desktop_Qt_5_4_1_MSVC2012_OpenGL_32bit-Debug"
"H:/cuteapps/session"
output 3:
"H:/cuteapps/build-untitled2-Desktop_Qt_5_4_1_MSVC2012_OpenGL_32bit-Debug"
"H:/cuteapps/session"

Embedding Lua to C++ and wxWidgets using Eclipse IDE

I am new to Lua so I am sorry if this is rather an easy question but it is driving me nuts. In my previous thread A simple query on calling Lua 5.2 from C++ I have used an easy C++ code to embed Lua in it. Things worked well but when I transfer that concept to a more complex project, the same code does not work. I have checked many sources but could not find a solution.
Here is my code:
#include "External/include/lua.hpp"
lua_State *luastate =NULL;
IMPLEMENT_APP(ScienceSuitApp);
bool ScienceSuitApp::OnInit()
{
luastate=luaL_newstate();
luaL_openlibs(luastate);
ScienceSuitFrame* frame = new ScienceSuitFrame(0L);
frame->Show();
return true;
}
Now when I try to compile the code, I am getting invalid arguments error for the luaL_openlibs(luastate) line. The error that the compiler gives:
Invalid arguments '
Candidates are:
void luaL_openlibs(*)
' ScienceSuitApp.cpp /ScienceLab line 33 Semantic Error
This is actually happening whenever I call a Lua function such as luaL_dostring etc.. which takes lua_State as parameter. By the way, I am using Eclipse as IDE and wxWidgets as GUI if that should give a clue. Any my configuration for this set up is:
I "think" I have solved the problem. It stems from the fact that Eclipse throws a "semantic error" and not a "syntax error". Therefore, I followed the advice from Eclipse CDT shows semantic errors, but compilation is ok. But now my question is what does it have to do with Indexing in Eclipse IDT? It feels like I am using Eclipse without knowing any of its internals.

Including C++ headers in user mode programs built with NT DDK

So...I have a kernel mode component and a user mode component I'm putting together using the turnkey build environment of the NT DDK 7.1.0. The kernel component is all .c/.h/.rc files. The user mode component is .cpp/.c/.h/.rc files.
At first it seemed simplest to use build for both, as I saw you could modify the ./sources file of the user mode component to say something like:
TARGETNAME = MyUserModeComponent
TARGETTYPE = PROGRAM
UMTYPE = windows
UMENTRY = winmain
USE_MSVCRT = 1
That didn't seem to cause a problem and so I was pleased, until I tried to #include <string> (or <memory>, or whatever) Doesn't find that stuff:
error C1083: Cannot open include file: 'string': No such file or directory
Still, it's compiling the user mode piece with C++ language semantics. But how do I get the standard includes to work?
I don't technically need to use the DDK build tool for the user mode piece. I could make a visual studio solution. I'm a bit wary as I have bumped into other annoyances, like the fact that the DDK uses __stdcall instead of __cdecl by default... and there isn't any pragma or compiler switch to override this. You literally have to go into each declaration you care about and change it, assuming you have source to do so. :-/
I'm starting to wonder if this is just a fractal descent into "just because you CAN doesn't mean you SHOULD build user mode apps with the DDK. Here be dragons." So my question isn't just about this particular technical hurdle, but rather if I should abandon the idea of building a C++ user mode component with the DDK tools...just because the kernel component is pure C.
To build a user mode program with WINDDK you need to add some variables to your SOURCES file:
386_STDCALL=0 to use cdecl calling convention by default
USE_STL=1 to use STL
USE_NATIVE_EH=1 to add a support for exception handling
Everything else you already have.
I'll put my full SOURCES file for reference:
TARGETNAME = MyUserModeComponent
TARGETTYPE = PROGRAM
TARGETPATH = obj
UMTYPE = console
UMENTRY = main
USE_MSVCRT = 1
USE_NATIVE_EH=1
USE_STL=1
386_STDCALL=0
SOURCES= main.cpp
And main.cpp:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s = "bla bla bla!";
cout << s;
return 0;
}
Have fun!
Quick Answer
Abandon the idea of building user-mode components with DDK tools (although I find the concept fascinating :-P)
Your kernel mode component should be built separately from the user mode components as a matter of good practice.
Vague thoughts
Off the top of my head, and this really speaking from limited experience...there are a lot of subtle differences that can creep up if you try to mix the two together.
Using your own example of __cdecl vs __stdcall; You have two different calling conventions. _cdecl is all kernel stuff and all of the C++ methods are wrapped around in WINAPI (_stdcall) passing conventions and __stdcall will clean do auto stack clean up and expect frame pointers inserted all over the place. And if you by accident use compiler options to trigger a __fastcall, it would be a pain to debug.
You can definitely hack something together, but do you really want to keep track of that in your user-space code and build environment? UGH I say.
Unless you have very specific engineering reasons to mix the two environments, (and no a unified build experience is not a valid reason, because you can get that from a batch file called buildall.bat) I say use the separate toolchains.

Why do I receive a SIGSEGV signal while using the Aria robotics API?

I am using the Aria C++ programming libs for mobile robots (http://robots.mobilerobots.com/wiki/ARIA). I am new to this API so I wanted to start with a simple action class derived from ArAction. Now I tried to develop a small test program (an ArAction) in order to
control a simulated p3dx robot via MobileSim. Development takes place under Ubuntu 10.10, using gcc 4.4.5. Making (compiling) my code works fine, without errors. I can also set the desired speed for example in my ArAction's fire() method, and the simulation is also working as desired.
But, unfortunately, I can't use the ArRobot object attached to the ArAction I am overriding. The problem is that none of the member functions of the ArRobot object seems to work. For example, calling getVel() or getCompass() always returns a zero value. And when I call the hasFrontBumpers() method the program even crashes with the error message "Aria: Received signal 'SIGSEGV'. Exiting.". As soon as I remove this method call and recompile the error is also gone again...
Here is the relevant code that leads to the crash:
ArActionDesired * forward::fire(ArActionDesired d)
{
desiredState.reset();
ArRobot *r = getRobot();
if(r == NULL)
{
printf("ArRobot = NULL\n");
deactivate();
return &desiredState;
}
printf("ok, ArRobot is not NULL, check for bumpers...\n");
r->hasFrontBumpers(); // <-- this leads to the SIGSEV-based "crash"
return &desiredState;
}
Any ideas what I am missing here -- is it a problem with my coding, or with the simulation environment? Thanks in advance for your help!
Kind regards, Matthias
ok, found it out now -- for the records: the Aria libs in version 2.7.2 are based on gcc-3 and libstdc++ 5, but Ubuntu 10.10 (which I am using) is shipped with gcc-4 and libstdc++ 6 per default. So I had to manually install the older versions of both packages, now my code is running fine...
cheers!
Calling hasFrontBumpers() for a p3dx from the fire() works fine for me on a similar Linux platform. If something is wrong, it is not in this method but in the initialization of the system. A reason for the non-moving robot could be that robot.enableMotors() hasn't been called.