I run wxwidgets 3.0.5 launched on Ubuntu 20.04. I am trying to read output from an application, which I launch with wxExecute().
Synchronous execution with wxExecute (wxSring & cmd, wxArrayString &output, wxArrayString &errors) works fine for me - I am getting the error and common outputs of the app correctly.
But I am having difficulties with asynchronous execution - wxExecute (const wxString &command, int flags=wxEXEC_ASYNC, wxProcess *callback=NULL). I cannot get the outputs from the streams, since the appear to be empty. Moreover, the returned status of the process is incorrect - should return 400, but returns - 112. Here is my code:
Code: Select all
/************************************APP DECLARATION*****************************
#ifndef MAIN_H
#define MAIN_H
#include <wx/wx.h>
#include <wx/process.h>
class MyProcess : public wxProcess {
public:
MyProcess(){}
// funkce, ktera se zavola po ukonceni procesu
virtual void OnTerminate(int pid, int status) override;
};
class MyApp : public wxApp, public wxFrame
{
public:
MyProcess * process;
virtual bool OnInit();
};
DECLARE_APP(MyApp)
#endif
#include "myApp.hpp"
IMPLEMENT_APP(MyApp)
/************************************APP IMPLEMENTATION*****************************
bool MyApp::OnInit()
{
wxString cmd;
wxArrayString output;
wxArrayString error;
uint velOut;
uint velErr;
int pid;
cmd = wxString::FromUTF8("a.out hey hii");
// synchronous exec
wxExecute(cmd, output, error);
//size of field
velOut = output.GetCount();
//write the elements
for(uint k=0; k<velOut; ++k){
std::cout << "size of out["<<k<<"] = " << output[k].Length() << std::endl;
std::cout << output[k].utf8_str() << std::endl;
}
//size of error field
velErr = error.GetCount();
//write down the elements
for(uint k=0; k<velErr; ++k){
std::cout << error[k].utf8_str() << std::endl;
}
//asynchronous execution
process = new MyProcess;
pid = wxExecute(cmd, wxEXEC_ASYNC, process);
//std::cout << "pid = " << pid << std::endl;
return true;
}
wxString getOutput(wxInputStream * iStream){
//wxTextInputStream * tiStream (*iStream, " \t", wxCSConv(wxFONTENCODING_UTF8));
char buffer[128];
buffer[iStream->Read(buffer, WXSIZEOF(buffer) - 1).LastRead()] = '\0';
return wxString::FromUTF8(buffer);
}
void MyProcess::OnTerminate(int ipid, int istatus){
wxString status;
wxString output;
wxString error;
// zapis statusu do chyboveho hlaseni do patricne polozky zaznamu dle akce
status = std::to_string(istatus).c_str();
// vycteni dat z procesu
if(IsInputAvailable()){
output = getOutput(GetInputStream());
std::cout << "OnTerminate: input available" << std::endl;
}
if(IsErrorAvailable()){
error = getOutput(GetErrorStream());
std::cout << "OnTerminate: error available" << std::endl;
}
//std::cout << "ipid = " << ipid << std::endl;
std::cout << "OnTerminate: status: "<< istatus << std::endl;
std::cout << "OnTerminate: output openeden: " << IsInputOpened() << std::endl;
std::cout << "OnTerminate: output: "<< output.length() << output.utf8_str() << std::endl;
std::cout << "OnTerminate: error: "<< error.length() << error.utf8_str() << std::endl << std::endl;
}
size of out[0] = 9
Pocet = 2
size of out[1] = 3
hey
size of out[2] = 3
hii
Chyba
Pocet = 2
hey
hii
ChybaOnTerminate: status: -112
OnTerminate: output openeden: 0
OnTerminate: output: 0
OnTerminate: error: 0
During the async execution, it appears, that the outputs are redirected to console instead of the wxwidgets program (see above). Can anybody tell me, how to obtain output from the app in the wxProcess::OnTerminate() function, when launched asynchronously? If you can point out, where I made a mistake in my code, It will be appreciated.
Here is code of the launched app a.out:
Code: Select all
#include <iostream>
int main(int argc, char *argv[]){
std::cout << "Pocet = " << argc - 1 << std::endl;
for(int k = 1; k < argc; ++k){
std::cout << argv[k] << std::endl;
}
std::cerr << "Chyba";
return 400;
}