I have write SDL code in vscode to pop the window and when i
compile it using g++ file.cpp -lSDL2 no error was thier but
when i run it by
"./a.out" it does not show any thing to me.
#include<iostream>
#include<SDL2/SDL.h>
using namespace std;
// main function
int main( int argc, char *args[] )
{
// Initialize SDL video sub system
if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
cout << endl << SDL_GetError();
// create a window and pop it
SDL_Window *window = SDL_CreateWindow( "SDL Linux", 100, 100, 700, 500, SDL_WINDOW_SHOWN );
// wait for 6 second
SDL_Delay(6000);
return 0;
}
//it should pop a window
Related
I have some .exe file (say some.exe) that writes to the standard output binary data. I have no sources of this program. I need to run some.exe from my C++/Qt application and read standard output of the process I created. When I'm trying to do this with QProcess::readAll someone replaces byte \n (0x0d) to \r\n (0x0a 0x0d).
Here is a code:
QProcess some;
some.start( "some.exe", QStringList() << "-I" << "inp.txt" );
// some.setTextModeEnabled( false ); // no effect at all
some.waitForFinished();
QByteArray output = some.readAll();
I tried in cmd.exe to redirect output to file like this:
some.exe -I inp.txt > out.bin
and viewed out.bin with hexedit there was 0a 0d in the place where should be 0d.
Edit:
Here is a simple program to emulate some.exe behaviour:
#include <stdio.h>
int main() {
char buf[] = { 0x00, 0x11, 0x0a, 0x33 };
fwrite( buf, sizeof( buf[ 0 ] ), sizeof( buf ), stdout );
}
run:
a.exe > out.bin
//out.bin
00 11 0d 0a 33
Note, that I can't modify some.exe that's why I shouldn't modify my example like _setmode( _fileno( stdout, BINARY ) )
The question is: how can I say to QProcess or to Windows or to console do not change CR with LF CR?
OS: Windows 7
Qt: 5.6.2
how can I say to QProcess or to Windows or to console do not change CR with LF CR?
They don't change anything. some.exe is broken. That's all. It outputs the wrong thing. Whoever made it output brinary data in text mode has messed up badly.
There's a way to recover, though. You have to implement a decoder that will fix the broken output of some.exe. You know that every 0a has to be preceded by 0d. So you have to parse the output, and if you find a 0a, and there's 0d before it, remove the 0d, and continue. Optionally, you can abort if a 0a is not preceded by 0d - some.exe should not produce such output since it's broken.
The appendBinFix function takes the corrupted data and appends the fixed version to a buffer.
// https://github.com/KubaO/stackoverflown/tree/master/questions/process-fix-binary-crlf-51519654
#include <QtCore>
#include <algorithm>
bool appendBinFix(QByteArray &buf, const char *src, int size) {
bool okData = true;
if (!size) return okData;
constexpr char CR = '\x0d';
constexpr char LF = '\x0a';
bool hasCR = buf.endsWith(CR);
buf.resize(buf.size() + size);
char *dst = buf.end() - size;
const char *lastSrc = src;
for (const char *const end = src + size; src != end; src++) {
char const c = *src;
if (c == LF) {
if (hasCR) {
std::copy(lastSrc, src, dst);
dst += (src - lastSrc);
dst[-1] = LF;
lastSrc = src + 1;
} else
okData = false;
}
hasCR = (c == CR);
}
dst = std::copy(lastSrc, src, dst);
buf.resize(dst - buf.constData());
return okData;
}
bool appendBinFix(QByteArray &buf, const QByteArray &src) {
return appendBinFix(buf, src.data(), src.size());
}
The following test harness ensures that it does the right thing, including emulating the output of some.exe (itself):
#include <QtTest>
#include <cstdio>
#ifdef Q_OS_WIN
#include <fcntl.h>
#include <io.h>
#endif
const auto dataFixed = QByteArrayLiteral("\x00\x11\x0d\x0a\x33");
const auto data = QByteArrayLiteral("\x00\x11\x0d\x0d\x0a\x33");
int writeOutput() {
#ifdef Q_OS_WIN
_setmode(_fileno(stdout), _O_BINARY);
#endif
auto size = fwrite(data.data(), 1, data.size(), stdout);
qDebug() << size << data.size();
return (size == data.size()) ? 0 : 1;
}
class AppendTest : public QObject {
Q_OBJECT
struct Result {
QByteArray d;
bool ok;
bool operator==(const Result &o) const { return ok == o.ok && d == o.d; }
};
static Result getFixed(const QByteArray &src, int split) {
Result f;
f.ok = appendBinFix(f.d, src.data(), split);
f.ok = appendBinFix(f.d, src.data() + split, src.size() - split) && f.ok;
return f;
}
Q_SLOT void worksWithLFCR() {
const auto lf_cr = QByteArrayLiteral("\x00\x11\x0a\x0d\x33");
for (int i = 0; i < lf_cr.size(); ++i)
QCOMPARE(getFixed(lf_cr, i), (Result{lf_cr, false}));
}
Q_SLOT void worksWithCRLF() {
const auto cr_lf = QByteArrayLiteral("\x00\x11\x0d\x0a\x33");
const auto cr_lf_fixed = QByteArrayLiteral("\x00\x11\x0a\x33");
for (int i = 0; i < cr_lf.size(); ++i)
QCOMPARE(getFixed(cr_lf, i), (Result{cr_lf_fixed, true}));
}
Q_SLOT void worksWithCRCRLF() {
for (int i = 0; i < data.size(); ++i) QCOMPARE(getFixed(data, i).d, dataFixed);
}
Q_SLOT void worksWithQProcess() {
QProcess proc;
proc.start(QCoreApplication::applicationFilePath(), {"output"},
QIODevice::ReadOnly);
proc.waitForFinished(5000);
QCOMPARE(proc.exitCode(), 0);
QCOMPARE(proc.exitStatus(), QProcess::NormalExit);
QByteArray out = proc.readAllStandardOutput();
QByteArray fixed;
appendBinFix(fixed, out);
QCOMPARE(out, data);
QCOMPARE(fixed, dataFixed);
}
};
int main(int argc, char *argv[]) {
QCoreApplication app(argc, argv);
if (app.arguments().size() > 1) return writeOutput();
AppendTest test;
QTEST_SET_MAIN_SOURCE_PATH
return QTest::qExec(&test, argc, argv);
}
#include "main.moc"
Unfortunately it has nothing to do with QProcess or Windows or console. It's all about CRT. Functions like printf or fwrite are taking into account _O_TEXT flag to add an additional 0x0D (true only for Windows). So the only solution is to modify stdout's fields of your some.exe with WriteProcessMemory or call the _setmode inside an address space of your some.exe with DLL Injection technique or patch the lib. But it's a tricky job.
I'm aware that the GetTcpTable2 api is supported only on windows vista and above versions, hence the code checks for the OS version and only then enters the loop that calls the api. I'm compiling the code on windows 7, visual studio 2008 and the executable runs fine on windows 7 and other OS except Windows XP, the error thrown is :
The code snippet is:`
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <stdio.h>
// Need to link with Iphlpapi.lib and Ws2_32.lib
#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
/* Note: could also use malloc() and free() */
int main()
{
OSVERSIONINFOEX osvi;
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
GetVersionEx((OSVERSIONINFO *)&osvi);
if(osvi.dwMajorVersion>=6)
{
// Declare and initialize variables
PMIB_TCPTABLE2 pTcpTable;
ULONG ulSize = 0;
DWORD dwRetVal = 0;
char szLocalAddr[128];
char szRemoteAddr[128];
struct in_addr IpAddr;
int i;
pTcpTable = (MIB_TCPTABLE2 *) MALLOC(sizeof (MIB_TCPTABLE2));
if (pTcpTable == NULL)
{
printf("Error allocating memory\n");
return 1;
}
ulSize = sizeof (MIB_TCPTABLE);
// Make an initial call to GetTcpTable2 to
// get the necessary size into the ulSize variable
if ((dwRetVal = GetTcpTable2(pTcpTable, &ulSize, TRUE)) ==
ERROR_INSUFFICIENT_BUFFER)
{
FREE(pTcpTable);
pTcpTable = (MIB_TCPTABLE2 *) MALLOC(ulSize);
if (pTcpTable == NULL)
{
printf("Error allocating memory\n");
return 1;
}
}
}
else
{
printf("Unsupported OS");
}
return 0;
}
`How do I get the executable to work on Windows XP without crashing/throwing the error shown in attached image?
I have tried below simple program to use XShmGetImage to get the desktop image.
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <X11/extensions/XShm.h>
#include <X11/extensions/Xfixes.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main(int argc, const char *argv[])
{
int screen;
Window root;
Display* display;
XImage* img,
int shm=0;
XShmSegmentInfo shminfo;
/* My Desktop Screen Resolution */
int width=1360;
int height=768;
display = XOpenDisplay(getenv("DISPLAY"));
shm = XShmQueryExtension(display);
if ( shm) {
printf ("Ha... QueryExtension Successful..\n");
int scr = XDefaultScreen (display);
printf ("\n Screen Number is %d ", scr);
img = XShmCreateImage (display, DefaultVisual(display, scr),
DefaultDepth ( display, scr),
ZPixmap,
NULL,
&shminfo,
width,
height);
printf ("\n Bytes Per Line %d ", img->bytes_per_line);
shminfo.shmid = shmget (IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT | 0777);
if ( shminfo.shmid == -1 ) {
printf ("\n Can not get the shared Memory ...");
} else {
printf ("\n Greate I am able to get shared memory..");
}
shminfo.shmaddr = img->data =shmat (shminfo.shmid, 0,0);
shminfo.readOnly = False;
if (!XShmAttach (display, &shminfo)) {
printf ("\n i am unable to attach now..");
} else {
printf ("\n Super.. i am able to attach Shared memory to extension ");
}
if ( !XShmGetImage (display, RootWindow(display, DefaultScreen(display)), img, 0,0, AllPlanes)){
printf ("\n Now you should have your image in XImage");
} else {
printf ("\n Ooops.. Something wrong.");
}
}
Output:
Ha... QueryExtension Successful..
Screen Number is 0
Bytes Per Line 5440
Greate I am able to get shared memory..
Super.. i am able to attach Shared memory to extension
Ooops.. Something wrong.
Unfortunately, XShmGetImage fails, and no information is displayed. Please help.
There was a blunder from my side. Actually, it works properly, and I misinterpreted the return value of XShmGetImage API().
The correct one is
if ( !XShmGetImage (display, RootWindow(display, DefaultScreen(display)), img, 0,0, AllPlanes)){
printf ("\n Ooops.. Something wrong.");
} else {
printf ("\n Now you should have your image in XImage");
}
I run this sample cod, and i get run time exception
#include "stdafx.h"
#include <iostream>
using namespace std;
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
using namespace cv;
int _tmain(int argc, char** argv)
{
//IplImage* img = cvLoadImage( "Walk1001.jpg" ,1 );
IplImage* img =cvLoadImage( argv[1] );
if(!img)
cout << "Could not open or find the image" << endl ;
cvNamedWindow( "Example1", 1 );
cvShowImage( "Example1", img );
cvWaitKey(0);
cvReleaseImage( &img );
cvDestroyWindow( "Example1" );
return 0;
}
when i use IplImage* img = cvLoadImage( "Walk1001.jpg" ,1 ); instead of this IplImage* img =cvLoadImage( argv[1] ); program runs fine. but otherwise i got error.
What is to do with argv. i have came across many programs in which image is loaded through some argv[] syntex! how to use this array (argv[]) or what else?
to use the argv array, you've got to supply arguments to your program (from the cmdline, or similar)
prog.exe Walk1001.jpg 19
now argv holds 3 elements, [ "prog.exe", "Walk1001.jpg", "19" ], and argc==3
in your program , do:
char * imgPath="Walk1001.jpg"; // having defaults is a good idea
if ( argc > 1 ) // CHECK if there's actual arguments !
{
imgPath = argv[1]; // argv[0] holds the program-name
}
int number = 24;
if ( argc > 2 ) // CHECK again, if there's enough arguments
{
number = atoi(argv[2]); // you get the picture..
}
sidenote: you seem to be a beginner (nothing wrong with that!), the opencv api has changed over the years, please don't use IplImage* and cv*Functions(the 1.0 api),
use cv::Mat and functions from cv:: namespace.
using namespace cv;
int main(int argc, char** argv)
{
char * imgPath="Walk1001.jpg";
if ( argc > 1 )
{
imgPath = argv[1];
}
Mat img = imread( imgPath );
if ( img.empty() )
{
cout << "Could not open or find the image" << endl ;
return 1;
}
namedWindow( "Example1", 1 );
imshow( "Example1", img );
waitKey(0);
// no, you don't have to release Mat !
return 0;
}
I am getting run time exception. the error is line 2482 unknown function in array.cpp? I think i get this message from imshow after debugging. I'm using Mat img=imread("walk100.jpg"); but the img.total() returning NULL. why imread is returning NULL. cvload is working perfectly.
I got this solved, on the web i came to know about ***d.dll. while adding dll files, I omitted the d, that is for release mode not for debug mode. So I just place "d", like opencv_core244d.dll instead of opencv_core244.dll
thanks all for your contribution
I'm learning to use xlib and I'm unable to get XChangeProperty() to work for me.
I have a simple program that displays a window successfully. But calls to XChangeProperty() always fail with error code error 1 (BadRequest).
Can someone tell me what I'm doing wrong?
Here is my code to change a property.
static void
change_prop(Display *display, Window window)
{
unsigned char some_text[40] = "hello world!";
int retval;
Atom my_atom;
my_atom = XInternAtom(display, "PERSONAL_PROPERTY", False);
if (my_atom == None)
{
printf("### failed to create atom with name PERSONAL_PROPERTY\n");
return;
}
retval = XChangeProperty(display, /* connection to x server */
window, /* window whose property we want to change */
my_atom, /* property name */
XA_STRING, /* type of property */
8, /* format of prop; can be 8, 16, 32 */
PropModeReplace,
some_text, /* actual data */
10 /* number of elements */
);
printf("###### XChangeProperty() reted %d\n", retval);
}
Most xlib functions always return 1 and you should use error handlers to check for errors. See XChangeProperty implementation - note return 1 at the end.
Your code works just fine:
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
static void
change_prop(Display *display, Window window)
{
unsigned char some_text[40] = "hello world!";
int retval;
Atom my_atom;
my_atom = XInternAtom(display, "PERSONAL_PROPERTY", False);
if (my_atom == None)
{
printf("### failed to create atom with name PERSONAL_PROPERTY\n");
return;
}
retval = XChangeProperty(display, /* connection to x server */
window, /* window whose property we want to change */
my_atom, /* property name */
XA_STRING, /* type of property */
8, /* format of prop; can be 8, 16, 32 */
PropModeReplace,
some_text, /* actual data */
10 /* number of elements */
);
printf("###### XChangeProperty() reted %d\n", retval);
}
int main()
{
Display *dis;
Window win;
dis = XOpenDisplay(NULL);
win = XCreateSimpleWindow(dis, RootWindow(dis, 0), 1, 1, 500, 500, \
0, BlackPixel (dis, 0), BlackPixel(dis, 0));
XMapWindow(dis, win);
printf("window %i\n", (int)win);
change_prop(dis, win);
XFlush(dis);
sleep(50);
return(0);
}
result:
09:48 tmp $ g++ prop.cpp /usr/X11/lib/libX11.dylib
09:48 tmp $ ./a.out
window 6291457
###### XChangeProperty() reted 1
xprop result:
09:48 tmp $ xprop -id 6291457
WM_STATE(WM_STATE):
window state: Normal
icon window: 0x0
_NET_WM_STATE(ATOM) =
_NET_WM_ALLOWED_ACTIONS(ATOM) = _NET_WM_ACTION_MOVE, _NET_WM_ACTION_RESIZE, _NET_WM_ACTION_MINIMIZE, _NET_WM_ACTION_MAXIMIZE_HORZ, _NET_WM_ACTION_MAXIMIZE_VERT, _NET_WM_ACTION_FULLSCREEN, _NET_WM_ACTION_CLOSE
PERSONAL_PROPERTY(STRING) = "hello worl"