I want to write log files. My application could be run on Linux and Windows. I've pretty much figured out how to do it for the former, thanks to this example:
void SyslogMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
Q_UNUSED(context)
QByteArray localMsg = msg.toLocal8Bit();
switch (type)
{
case QtDebugMsg:
#ifdef __linux__
syslog(LOG_DEBUG, "Message (debug): %s", localMsg.constData());
#elif _WIN32
// WRITE INTO FILE
#else
#endif
break;
// etc.
}
}
int main()
{
// Install our message handler.
qInstallMessageHandler(SyslogMessageHandler);
// Send some messages, which should go to syslog.
qDebug("Debug log message from Qt test program");
}
source (2nd example)
However, I am wondering what would be the fastest way for Windows? Is using QFile or QTextStream an efficient way for writing this kind of information?
I was thinking about storing everything in a simple QString and then put everything in a file when the app closes or crashes (in the latter case, is that possible?).
Related
I'm currently working on Arduino. I'm working for Lamp using Atmega1284. I saw an example code, ModbusIP_ENC28J60 -> Lamp. I first compiled it without adding anything, it compiled properly. Now, I'm adding WebSocketServer, since I want this to work on websocket too. I added few necessary lines, but I ended up with this error:
error: 'EthernetClass Ethernet' redeclared as different kind of symbol
I don't understand what's wrong with the code or what I should change. Can someone help me with this?
I'm pasting my code here for reference:
#include <EtherCard.h>
#include <Modbus.h>
#include <ModbusIP_ENC28J60.h>
#include <WebSocketsServer.h>
WebSocketsServer webSocketServer = WebSocketsServer(8080);
//Modbus Registers Offsets (0-9999)
const int LAMP1_COIL = 100;
//Used Pins
const int ledPin = 9;
//ModbusIP object
ModbusIP mb;
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght) {
switch(type) {
case WStype_DISCONNECTED:
Serial.println("[%u] Disconnected!\n");
break;
case WStype_CONNECTED:
{
//IPAddress ip = webSocket.remoteIP(num);
Serial.println("[%u] Disconnected!\n");
// send message to client
//webSocket.sendTXT(num, "Connected");
}
break;
case WStype_TEXT:
Serial.println("[%u] got text!\n");
// send message to client
// webSocket.sendTXT(num, "message here");
// send data to all connected clients
// webSocket.broadcastTXT("message here");
break;
case WStype_BIN:
Serial.println("[%u] get binary ");
//hexdump(payload, lenght);
// send message to client
// webSocket.sendBIN(num, payload, lenght);
break;
}
}
void setup() {
// The media access control (ethernet hardware) address for the shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// The IP address for the shield
byte ip[] = { 192, 168, 0, 120 };
//Config Modbus IP
mb.config(mac, ip);
//Set ledPin mode
pinMode(ledPin, OUTPUT);
// Add LAMP1_COIL register - Use addCoil() for digital outputs
mb.addCoil(LAMP1_COIL);
webSocketServer.begin();
webSocketServer.onEvent(webSocketEvent);
}
void loop() {
//Call once inside loop() - all magic here
mb.task();
//Attach ledPin to LAMP1_COIL register
digitalWrite(ledPin, mb.Coil(LAMP1_COIL));
webSocketServer.loop();
}
Help me to make it work.
You are declaring Ethernet twice. And they are different.
First is probably in the include file Ethercard.h
Second is Modbus.h
In the ModbusIP_ENC28J60 I found in github via Google they declare Ethernet as an array.
Either rename one declaration (e.g. ether vs Ethernet) or eliminate the use of one. Also, considering the include files in your source I would be surprised if there are only two conflicts.
C lesson: Declaring a variable for use by a function, very straightforward. When adding additional modules any name conflicts will cause problems. If you get two variables to agree but are still in the program you will suffer massive debugging headaches because one function will access its variable while the other will have its own, resulting in nothing actually working.
Go back and look at the source files (*.h). Search for "Ethernet" variables. See how they are declared and how they are used. The simplest solution is to pick the latest addition and change Ethernet to ether (as I suggested above).
Good Luck.
I am using Qt 4.8. Is there any way to have a global try and catch block for whole project. Example, if my application has two .cpp files. Is it possible way to catch exception across both .cpp files?
First of all, be warned that Qt doesn't play nice with exceptions. It was designed back in those days when exceptions were rather obscure feature of C++ so the use of exceptions was not generally considered a good practice for a whole bunch of implementation-related reasons.
Also be warned that as of Qt 5.7 the exception safety is not feature complete as the official doc currently tells:
Preliminary warning: Exception safety is not feature complete! Common cases should work, but classes might still leak or even crash.
If you use signal-slot connections within your classes, it's best to handle exceptions inside the slots which may throw them. As of Qt 5.7 not doing so is considered undefined behaviour.
If you just want to do some cleanup and/or error logging on any occasionally uncaught exception, you can either wrap the entire main() contents into try/catch block as the previous answer suggests or alternatively you can wrap the Qt's main event loop into such a block:
QApplication app(argc, argv);
...
try {
app.exec();
}
catch (const std::exception &) {
// clean up here, e.g. save the session
// and close all config files.
return 0; // exit the application
}
You can put in brackets the entire contents of your main() function as follows::
int main(int argc, char *argv[])
{
int ret = 0;
try
{
QApplication a(argc, argv);
QWidget w;
w.show();
ret = a.exec();
}
catch(...)
{
/* ... */
}
return ret;
}
See also: std::set_terminate()
I write the code in I/O Kit Driver template in the following way:
#include <IOKit/IOService.h>
class com_osxkernel_driver_IOKitTest : public IOService
{
OSDeclareDefaultStructors(com_osxkernel_driver_IOKitTest)
public:
virtual bool init (OSDictionary* dictionary = NULL);
virtual void free (void);
virtual IOService* probe (IOService* provider, SInt32* score);
virtual bool start (IOService* provider);
virtual void stop (IOService* provider);
};
#include "IOKitTest.h"
#include <IOKit/IOLib.h>
#define super IOService
OSDefineMetaClassAndStructors(com_osxkernel_driver_IOKitTest, IOService)
bool com_osxkernel_driver_IOKitTest::init (OSDictionary* dict)
{
bool res = super::init(dict);
IOLog("IOKitTest::init\n");
return res;
}
void com_osxkernel_driver_IOKitTest::free(void)
{
IOLog("IOKitTest::free\n");
super::free();
}
IOService* com_osxkernel_driver_IOKitTest::probe (IOService* provider, SInt32* score)
{
IOService *res = super::probe(provider, score);
IOLog("IOKitTest::probe\n");
return res;
}
bool com_osxkernel_driver_IOKitTest::start (IOService *provider)
{
bool res = super::start(provider);
IOLog("IOKitTest::start\n");
return res;
}
void com_osxkernel_driver_IOKitTest::stop (IOService *provider)
{
IOLog("IOKitTest::stop\n");
super::stop(provider);
}
When I build this code, I get four errors:
Expected function body after function declarator
stray '\357' in program
stray '\277' in program
stray '\274' in program
Can you see the error?
Can you see the error?
No. But the compiler can. And Xcode will show it to you.
I pasted your code into a new project and did compile it:
All three stray characters are in the same part of the code.
If such a stray '\something' error happens you have a character in your code that can't be compiled, and you usually can't see them. They often come from a copy and paste that went wrong.
Just delete the line with the error and write it again. Don't copy and paste or anything.
I took that part of the code and opened it in a hex editor. So you can see where these errors come from.
For anyone that uses KATE (KDE Advanced Text Editor), I was able to fix similar 'stray errors' by opening up the files causing the error and Unchecking the "Add Byte Order Mark (BOM)" option which can be found under the Tools menu. The file will not appear to have been changed after you uncheck this setting so you will need to actually save (Ctrl+S) the file. When you re-compile, the error will be gone.
I am developing a NPAPI plugin using firebreath. I am using a third party dll to integrate to a gaming device.The inputs on the devices are propagated to the plugin through a message only window(HWND) registered while opening a channel to the device.
Initially, handshake with the device driver,
handshake(HWND,...) and after which on user input, a callback is made on CustomWinProc() to notify.
I did the following,
-Created an Header&CPP file under the WIN-CustomCallbackHandler.h ,
#include "Win\PluginWindowWin.h"
#include "Win\WindowContextWin.h"
class CustomCallbackHandler : public FB::PluginWindowWin
{
public:
CustomCallbackHandler (const FB::WindowContextWin& ctx);
protected:
virtual bool CustomWinProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM
lParamm,LRESULT & lRes);
};
-CustomCallbackHandler.cpp
[code]
#include "CustomCallbackHandler.h"
#include "PluginWindowForwardDecl.h"
#include "Win\WindowContextWin.h"
#include "Win\PluginWindowWin.h"
CustomCallbackHandler::CustomCallbackHandler(const FB::WindowContextWin& ctx) :
FB::PluginWindowWin(ctx){
}
bool CustomCallbackHandler::CustomWinProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM
lParamm,LRESULT & lRes){
//if WPARAM is something some operation has to be performed.
return false;
}
[/code]
-Factory.cpp - Added the following method to override the PluginWindowWin
FB::PluginWindowWin* createPluginWindowWin(const FB::WindowContextWin& ctx)
{
return new CustomCallbackHandler(ctx);
}
-MyFirstPluginAPI.cpp-(The auto generated JSAPIAuto subclass)- JS method.
bool MyFirstPluginAPI::handshake(FB::JSObjectPtr &callback)
{
FB::WinMessageWindow window;
thirdpartymethod(window.getHWND());
}
Now,When I debug I could see the customcallbackhandler being invoked a couple of times for the regular plugin events but the events generated by the devices are not available.I believe a different instance of message window is passed on to the dll.
-How do I get the handle of the PluginWindowWin?
-Once I receive a callback on the CustomCallbackHandler,How do I generate a custom sendEvent()?
Your help is highly appreciated.
I am a Java developer and don't have much experience in C++ programming. I believe I am missing something fundamental.
What you want is to use WinMessageWindow:
https://github.com/firebreath/FireBreath/blob/master/src/PluginCore/Win/WinMessageWindow.h
You don't want to use PluginWindowWin; that's too specific for other things. WinMessageWindow was created specifically to do the types of things you are trying to do, and it allows you to make a winproc handler on the containing class.
I recently posted an example of using WinMessageWindow in order to receive WM_DEVICENOTIFY messages; I'm sure you can use it as an example of how the class works to get you started.
I was going over the examples of boost.asio and I am wondering why there isn't an example of a simple server/client example that prints a string on the server and then returns a response to the client.
I tried to modify the echo server but I can't really figure out what I'm doing at all.
Can anyone find me a template of a client and a template of a server?
I would like to eventually create a server/client application that receives binary data and just returns an acknowledgment back to the client that the data is received.
EDIT:
void handle_read(const boost::system::error_code& error,
size_t bytes_transferred) // from the server
{
if (!error)
{
boost::asio::async_write(socket_,
boost::asio::buffer("ACK", bytes_transferred),
boost::bind(&session::handle_write, this,
boost::asio::placeholders::error));
}
else
{
delete this;
}
}
This returns to the client only 'A'.
Also in data_ I get a lot of weird symbols after the response itself.
Those are my problems.
EDIT 2:
Ok so the main problem is with the client.
size_t reply_length = boost::asio::read(s,
boost::asio::buffer(reply, request_length));
Since it's an echo server the 'ACK' will only appear whenever the request length is more then 3 characters.
How do I overcome this?
I tried changing request_length to 4 but that only makes the client wait and not do anything at all.
Eventually I found out that the problem resides in this bit of code in the server:
void handle_read(const boost::system::error_code& error,
size_t bytes_transferred) // from the server
{
if (!error)
{
boost::asio::async_write(socket_,
boost::asio::buffer("ACK", 4), // replaced bytes_transferred with the length of my message
boost::bind(&session::handle_write, this,
boost::asio::placeholders::error));
}
else
{
delete this;
}
}
And in the client:
size_t reply_length = boost::asio::read(s,
boost::asio::buffer(reply, 4)); // replaced request_length with the length of the custom message.
The echo client/server is the simple example. What areas are you having trouble with? The client should be fairly straightforward since it uses the blocking APIs. The server is slightly more complex since it uses the asynchronous APIs with callbacks. When you boil it down to the core concepts (session, server, io_service) it's fairly easy to understand.