Is it possible to run a Qt gui application as a boost module through python? It was working as a standard C++ executable, but now I'm compiling it down to a shared library and trying to launch it from python. Right now it just goes into the python interpreter every time I run simpleMain() from the interpreter. As in, I get a new "Python 2.7.1+ (r271:86832, Apr 11 2011, 18:05:24)" greetings every time and my program segfaults when I close the interpreter. Also, I can't call the main function directly because I'm not sure how to convert a python list to a char*. A string to char seems to wrok naturally.
This is my python code to launch it:
import libsunshine
libsunshine.simpleMain()
and here's my C++ code:
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
using namespace boost::python;
BOOST_PYTHON_MODULE(libsunshine)
{
def("say_hello", say_hello);
def("simpleMain", simpleMain);
def("main", main);
}
int simpleMain()
{
char* args[] = {};
main(0,args);
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Sunshine w;
w.show();
return a.exec();
}
You can write your application setup in PyQt, which is as simple as
import sys
from PyQt4 import QtGui
QtGui.QApplication(sys.argv)
at the beginning of your script. Then can call c++ code in your modules which can open/close/... windows. (I have code which works this way)
I think it is illegal to call main in c++, which might be perhaps the reason for segfault.
Hmm usually main is called with
argc == 1
even when there are no params, argc[0] being the executable name.
Also argv is expected to be a list of pointers to strings terminated with a null pointer, while you're passing nothing. Depending on how QApplication parses the argument list (it may loop depending on argc, or it may just look for a null pointer), it can crash if passed even an argc of zero.
Try
char *args[1] = { NULL }; main(0, args);
or
char *args[2] = { "Dummy name", NULL }; main(1, args);
Related
I'm unable to get command line argument with int main(int argc, char* argv[]), No errors occurs but when further manipulation want to happen i see that argv[ ] and other related variables dont have any value and says Error reading characters of string then an Acces violation reading location error happens.
This is the sample code of my issue, I had to downsize it to make it readable:
#include "CommonHeaders.h"
void Start(char *input)
{
lstrcpyA(host, input);
// In this point i see in my Debugger "Locals/Autos" that nothing
// is passed to function then a "Access violation ... " happens.
// ...
}
int main(int argc, char *argv[])
{
Start(argv[1]);
return 0;
}
I always use this int main(int argc, char* argv[]) and pass command arg with ProjectProperties->Debugging->Command Argument and works perfect everytime. Is it possible that proper headers aren't included or any changes in project configuration could make a conflict?
Be sure to set the subsystem to console Linker -> SubSytem -> Console (/SUBSYSTEM:CONSOLE) and dont set an Entry point set the Whole Program Optimization to No Whole Program Optimization and turn SDL check to off.
I need to call a subproject from a main project and implemented two ways of doing that.
It turns out, that the second way is a factor 4 slower than the first.
Can anybody explain this to me?
The subproject looks like this:
#include "fancyProject.h"
int main (int argc, char *argv[])
{
std::string controlFile = argv[1];
return runFancyProject(controlFile);
}
First way: Call the binary of the subproject in the main project via the system() function:
std::string command = "fancyProject controlFile.dat";
int result = system(command.c_str());
Second way: Create a library from the subproject, link this library with the main project and call the specific function:
#include "fancyProject.h"
std::string controlFile = "controlFile.dat";
int result = runFancyProject(controlFile);
In the meantime, I created a minimal example. However, it behaves as expected: The system() function is slower than the call of the linked function. Thus, the error has to be somewhere else in the project. Nevertheless thank you very much for your time, especially to dsboger. I will do further investigations in this direction.
I'm trying to use wxWidgets to create a open/save FileDialog window in a cross-platform way. So I've looked at the examples in the documentation. I also want to create standalone windows, with no parent, because I am not using any other instance of a wxApp/wxWindow elsewhere in my program.
Additionally, I need to have my own main function, so I don't want to use a macro such as IMPLEMENT_APP. I tried to follow the instructions given here, and came up with the following minimal program:
#include <wx/wx.h>
#include <string>
#include <iostream>
std::string openFile() {
wxFileDialog openFileDialog(NULL, _("Open XYZ file"), "", "",
"XYZ files (*.xyz)|*.xyz", wxFD_OPEN|wxFD_FILE_MUST_EXIST);
if (openFileDialog.Show() == wxID_CANCEL)
return ""; // the user changed idea...
// proceed loading the file chosen by the user;
return "something";
}
int main(int argc, char *argv[]) {
std::cout << wxEntryStart(argc, argv) << std::endl;
std::string s = openFile();
wxEntryCleanup();
}
And here is the CMakeLists.txt I used to compile the code:
CMake_Minimum_Required(VERSION 2.8.11)
Project(test)
Find_Package(wxWidgets REQUIRED)
Include(${wxWidgets_USE_FILE})
Add_Executable(test main.cpp)
Target_Link_Libraries(test ${wxWidgets_LIBRARIES})
Still, when I run this program, I get a Segmentation Fault, despite the wxEntryStart returning true, and I have no idea where the problem comes from. Any tip?
I wouldn't be so bold with stripping down wx's initialization code. It may work today, but in the next version, who knows...
This is what I use:
class MyApp : public wxApp { };
wxIMPLEMENT_APP_NO_MAIN(MyApp);
int main()
{
wxDISABLE_DEBUG_SUPPORT();
int dummy = 0;
if(!wxEntryStart(dummy, static_cast<wxChar**>(nullptr)))
return 1;
auto onx1 = on_exit([]{ wxEntryCleanup(); }); //using RAII for cleanup
//Other initialization, create main window, show it.
wxGetApp().OnRun(); //This starts the event loop.
//In your case, it looks like ShowModal's event loop is enough,
//so you don't need this.
}
I think those macros, ugly as they are, provide much better insulation against future changes in the library initialization code.
Ok, after some fiddling here is a code sample that works for me. Comments welcome on what'd be the best practices. What I did was keep ShowModal() instead of Show() in the openFile function. I also created the instance of singleton wxApp. The final code is here:
#include <wx/wx.h>
#include <string>
#include <iostream>
std::string openFile() {
wxFileDialog openFileDialog(NULL, _("Open XYZ file"), "", "",
"XYZ files (*.xyz)|*.xyz", wxFD_OPEN|wxFD_FILE_MUST_EXIST);
if (openFileDialog.ShowModal() == wxID_CANCEL)
return ""; // the user changed idea...
// proceed loading the file chosen by the user;
return "something";
}
int main(int argc, char *argv[]) {
wxApp::SetInstance( new wxApp() );
wxEntryStart(argc, argv);
std::string s = openFile();
wxEntryCleanup();
}
Not sure this is completely leak-free, as valgrind seems to complain a little after exit. Any tip about whether I could also put the wxEntryStart() in the openFile() function welcome (I am guaranteed that this is the only place where the wxWidgets lib is used, and I want an API as simple as possible).
I've been working on this program using Qt in c++ and so far so good. However I then needed to get this program moved to another machine. I have subversion, so I committed every file in the project folder and checked it out on the new machine. After jumping through some hoops to get it to successfully build and running, I get this error:
ASSERT: "dst.depth() == 32" in file qgl.cpp,.
invalid parameter passed to c runtime function qt
I tried stepping through the program to find the point where it crashes and found that it was after everything had been initialized and show() is called for the class that inherits the QMainWindow class. The c->showView() line calls QMianWindow->show().
----------main.cpp------------
#include <QApplication>
#include "ModelI.h"
#include "ControllerI.h"
#include "Model.h"
#include "Controller.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ModelI *m = new Model();
ControllerI *c = new Controller(m);
c->showView(); <- ERROR HERE
return a.exec();
}
The confusing part of the problem is that the program works perfectly fine on my machine when show() is called. I don't know what could be different between the two machines to make the program behave so differently. Both use the same version of Qt (SDK 2010.05). Both are developing with Eclipse. The only difference I can find is that my compiler is MinGW 4.5.0 and the other machine's is MinGW 4.5.2.
EDIT 1:
This is what Controller::showView() looks like.
void Controller::showView()
{
mView->show();
}
And this is how mView is initialized.
mView = new View(mModel, this);
I have a piece of C++ code that calls the system command.. I want to pass the file name of my own C++ executable to the system command.. anyone know how to do this?
So for example my C++ code is called "switch-5".. what I want to do is something like;
system("./script.sh switch-5");
Anyone have any clue?
Your executable name is the first argument passed in argv.
To test this just run:
int main(int argc, char **argv)
{
printf("My program name: '%s'\n", argv[0]);
return 0;
}
(I am assuming you know how to combine it with your script name to get the string to pass to system().)
argv[0] as passed to main is the name of your executable.
Store it in a global variable during app startup:
static char *selfname;
int main(int argc, char **argv)
{
selfname = argv[0];
// etc.
}
Beware, argv[0] contains exactly what was used to start the program, including relative or absolute path, for example: "./programname".