I'm using QT5 and starting out with a basic Server/Client setup. I'm looking at going single threaded for both apps as there is no heavy processing on network data. Now, from everything I've read and researched here, when using asynchronous approach, you don't use waitForXXXX() otherwise it messes up all the signals and slots. The problem - On the client end, the connected() signal is either never emitted or never processed, even though the server consoles tells me that a new client has connected. I've been working on the same issue for 2 weeks now and couldn't find the exact same issue anywhere. I've stripped back both apps to the minimum and still no luck - also stripped out the UI part now - I just want see the console working. I have also tried switching to public slots and changing the signal/slot connection type and still have the same problem.
If you require code from the server, please let me know, but here is the basics of the client:
main.cpp
#include "QGameSocket.h"
#include <QtWidgets/QApplication>
#include <windows.h>
int main(int argc, char *argv[])
{
AllocConsole();
freopen( "conin$", "r", stdin );
freopen( "conout$", "w", stdout );
freopen( "conout$", "w", stderr );
QApplication a( argc, argv );
QGameSocket* pSocket = new QGameSocket();
return a.exec();
}
QGameSocket.h
#ifndef _QGAMESOCKET_H
#define _QGAMESOCKET_H
#include <QtNetwork/qtcpsocket.h>
#pragma comment ( lib, "Qt5Network.lib" )
class QGameSocket: public QObject
{
Q_OBJECT
public:
explicit QGameSocket( QObject* pParent = 0 );
~QGameSocket();
private slots:
void __OnConnected();
void __OnReadyRead();
private:
QTcpSocket* m_pSocket;
};
#endif
QGameSocket.cpp
#include "QGameSocket.h"
#include <qdatastream.h>
QGameSocket::QGameSocket( QObject* pParent ) :
QObject( pParent )
{
m_pSocket = new QTcpSocket();
connect( m_pSocket, SIGNAL( connected() ), this, SLOT( __OnConnected() ) );
connect( m_pSocket, SIGNAL( readyRead() ), this, SLOT( __OnReadyRead() ) );
const QString strHost = "127.0.0.1";
qDebug() << "Connecting to host ...";
m_pSocket->connectToHost( strHost, 27015 );
}
QGameSocket::~QGameSocket()
{
m_pSocket->deleteLater();
}
void QGameSocket::__OnConnected()
{
qDebug() << "Successfully connected to host!";
}
void QGameSocket::__OnReadyRead()
{
//handle messages
}
Any help would be much appreciated, thank you!
I finally figured it out - I was using the release network library, not the debug library.
I changed:
#pragma comment ( lib, "Qt5Network.lib" )
to
#pragma comment ( lib, "Qt5Networkd.lib" )
Related
I have a program using cpprestsdk for http querying and websocketpp for subscribing a data stream. The program will crash immediately(it says Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)). But if I comment either of the http querying or subcribing data stream, the program won't crash.
#include <websocketpp/config/asio_client.hpp>
#include <websocketpp/client.hpp>
#include "json.hpp"
#include <iostream>
#include <ctime>
#include <iostream>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
#include <vector>
#include <string>
using std::string;
using namespace web;
using std::cout, std::endl;
using std::vector;
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;
typedef websocketpp::client<websocketpp::config::asio_tls_client> client;
typedef websocketpp::config::asio_client::message_type::ptr message_ptr;
void on_stream_data(websocketpp::connection_hdl hdl, message_ptr msg) {
}
class OrderBook {
public:
void initialize() {
web::http::client::http_client_config cfg;
std::string uri = string("https://fapi.binance.com/fapi/v1/depth?symbol=btcusdt&limit=1000");
web::http::client::http_client client(U(uri), cfg);
web::http::http_request request(web::http::methods::GET);
request.headers().add("Content-Type", "application/x-www-form-urlencoded");
web::http::http_response response = client.request(request).get();
}
int start_stream() {
client c;
std::string uri = string("wss://fstream.binance.com/ws/btcusdt#depth#100ms");
try {
c.set_access_channels(websocketpp::log::alevel::all);
c.clear_access_channels(websocketpp::log::alevel::frame_payload);
c.init_asio();
c.set_message_handler(bind(on_stream_data, ::_1, ::_2));
websocketpp::lib::error_code ec;
client::connection_ptr con = c.get_connection(uri, ec);
if (ec) {
std::cout << "could not create connection because: " << ec.message() << std::endl;
return 0;
}
c.connect(con);
c.run();
} catch (websocketpp::exception const &e) {
std::cout << e.what() << std::endl;
}
}
};
int main(int argc, char *argv[]) {
OrderBook ob;
ob.initialize(); // comment either of these two lines, the program won't crash, otherwise the program will crash once start
std::this_thread::sleep_for(std::chrono::milliseconds(10000000));
ob.start_stream(); // comment either of these two lines, the program won't crash, otherwise the program will crash once start
}
When I run this program in Clion debug mode, Clion show that the crash comes from function in /opt/homebrew/Cellar/boost/1.76.0/include/boost/asio/ssl/detail/impl/engine.ipp
int engine::do_connect(void*, std::size_t)
{
return ::SSL_connect(ssl_);
}
It says Exception: EXC_BAD_ACCESS (code=1, address=0xf000000000)
What's wrong with it? is it because I run two pieces of code using boost::asio, and something shouldn't be initialized twice?
I can compile this and run it fine.
My best bet is that you might be mixing versions, particularly boost versions. A common mode of failure is caused when ODR violations lead to Undefined Behaviour.
Note that these header-only libraries depend on a number of boost libraries that are not header-only (e.g. Boost System, Thread and/or Chrono). You need to compile against the same version as the libraries you link.
If you use distribution packaged versions of any library (cpprestsdk, websocketpp or whatever json library that is you're using) then you'd be safest also using the distribution packaged version of Boost.
I'd personally simplify the situation by just using Boost (Beast for HTTP/websocket, Json for, you guessed it).
Running it all on a test Ubuntu 18.04 the OS Boost 1.65 version, the start_stream sequence triggers this informative error:
[2022-05-22 13:42:11] [fatal] Required tls_init handler not present.
could not create connection because: Connection creation attempt failed
While being UBSAN/ASAN clean. Perhaps that error helps you, once you figure out the configuration problems that made your program crash.
How can I change state of the camera flash throgh JNI function? I am looking to be able to have ON/OFF state control, just like in Java CameraManager.setTorchMode(cameraId, state); method. I've tried to search for it in native camera API ,but no success. Here's what I have done so far:
#include <jni.h>
#include <assert.h>
#include <jni.h>
#include <pthread.h>
#include <android/native_window_jni.h>
#include <camera/NdkCameraDevice.h>
#include <camera/NdkCameraManager.h>
#include <android/asset_manager.h>
#include "messages-internal.h"
JNIEXPORT void JNICALL
Java_com_android_rxjava_flashlightflicker_MainActivity_flasher(JNIEnv *env, jobject instance) {
ACameraIdList *cameraIdList = NULL;
const char *selectedCameraId = NULL;
ACameraManager *cameraManager = ACameraManager_create();
camera_status_t camera_status = ACAMERA_OK;
camera_status = ACameraManager_getCameraIdList(cameraManager, &cameraIdList);
/// Camera status not ok
if (camera_status != ACAMERA_OK) {
LOGE("Camera is bad id: %d \n", camera_status);
return;
}
// There is no camera
if (cameraIdList->numCameras < 1 ) {
LOGE("Camera is not present on the device.");
return;
}
selectedCameraId = cameraIdList->cameraIds[0];
ACameraMetadata *cameraMetedata = NULL;
ACameraManager_getCameraCharacteristics(cameraManager, selectedCameraId, &cameraMetedata);
// ACaptureSessionOutput_create()
}
I also tried to look in asset manager but no success, can anybody experienced with NDK camera give me a hand with it?
Thanks in advance!
This method is only available in Java API. You could access it through JNI, but IMO it would be easier and safer to write a wrapper static method in Java and have this wrapper called from your C++ code.
I'm working with wxWidgets 2.8 on a MOTIF (sic) linux box.
I noticed that wxListView and wxListCtrl don't refresh correctly their content after a scroll. When I act on the scrollbar, the new items are invisible until I click on them.
The misbehaviour is present also in the sample "listctrl" that comes with the wxWidgets library.
How can I solve this problem?
It seems it's a wxWidgets bug.
My first try was to work-around it by refreshing the wxListView after a scroll. Unfortunately, it seems wxWidgets doesn't provide scroll events for wxListView/wxListCtrl.
Finally, I solved my problem using the following ListView instead of wxListView in my code:
// listview.h
#ifndef LISTVIEW_H_
#define LISTVIEW_H_
#include <wx/listctrl.h>
class RefreshingListView : public wxListView, private wxTimer
{
public:
RefreshingListView( wxWindow *parent, wxWindowID id,
const wxPoint &pos=wxDefaultPosition,
const wxSize &size=wxDefaultSize,
long style=wxLC_ICON,
const wxValidator &validator=wxDefaultValidator,
const wxString &name=wxListCtrlNameStr ) :
wxListView( parent, id, pos, size, style, validator, name ),
lastTopItem( GetTopItem() )
{
Start( 300 ); // ms
}
// override
virtual void Notify() { CheckTopItem(); }
private:
void CheckTopItem()
{
long it = GetTopItem();
if ( it != lastTopItem )
{
Refresh();
lastTopItem = it;
}
}
long lastTopItem;
};
#ifdef __WXMOTIF__
typedef RefreshingListView ListView;
#else
typedef wxListView ListView;
#endif
#endif // LISTVIEW_H_
Maybe it can be useful to someone :-)
Good morning !
I have recently read articles quite interesting about hooking functions, I have followed one or two tutorials but it never seems to work, I am using Detoured and here is the full code which seems to me perfectly normal :(
#include <stdio.h>
#include <windows.h>
#include "stdafx.h"
#include "detours.h"
#pragma comment(lib, "detours.lib")
int(__stdcall* realFunc)(int) = (int(__stdcall*)(int))(0x004157B0);
void hookedFunc(int num)
{
printf("Test : %d\n", num + 100);
}
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
DetourAttach((PVOID*)(&realFunc), (PVOID)hookedFunc);
break;
case DLL_THREAD_ATTACH:
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach((PVOID*)(&realFunc), (PVOID)hookedFunc);
DetourTransactionCommit();
hookedFunc(100);
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
DetourDetach((PVOID*)0x004157B0, hookedFunc);
break;
}
return TRUE;
}
When using RemoteDLL and a simple console application as dummy to hook the function, all steps are completed successfully (running as administrator), the memory address to the function I want to be hooked matches, however the code line "printf("Test : %d\n", num + 100);" is not executed, the result does not appears at screen...
If anyone would have an idea about what's going on I would be really happy to hear it !
Thanks in advance !
First, hookedFunc must have the same signature: int __stdcall hookedFunc(int x).
I suppose the following effect of your code: hookedFunc is called each time somebody calls the function at address 0x004157B0. Is it what you expect?
For testing, you call this address. Let me change the code a little to clarify:
extern int __stdcall FunctionIWantToHook(int);
int(__stdcall* realFunc)(int) = FunctionIWantToHook;
...
DetourAttach((PVOID*)(&realFunc), (PVOID)hookedFunc);
FunctionIWantToHook(100); // hookedFunc will be called here
I have created a GUI using tcl. I want to make some of the core functionalities of the tcl code available to be used by any program which supports dll. For that i have taken a very simple tcl code example, which adds two integer numbers and i have written a c wrapper function to use this functionality. This is working for me. Now how can i create a dll for these two c and tcl files, so that any program can use this addition functionality by simply loading the dll.
Here is my simple tcl code :
/* Filename : simple_addition.tcl */
#!/usr/bin/env tclsh8.5
proc add_two_nos { } {
set a 10
set b 20
set c [expr { $a + $b } ]
puts " c is $c ......."
}
And here is my c wrapper function which uses the above tcl addition functionality :
#include <tcl.h>
#include <tclDecls.h>
#include <tclPlatDecls.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char **argv) {
Tcl_Interp *interp;
int code;
char *result;
printf("inside main function \n");
Tcl_FindExecutable(argv[0]);
interp = Tcl_CreateInterp();
code = Tcl_Eval(interp, "source simple_addition.tcl; add_two_nos");
/* Retrieve the result... */
result = Tcl_GetString(Tcl_GetObjResult(interp));
/* Check for error! If an error, message is result. */
if (code == TCL_ERROR) {
fprintf(stderr, "ERROR in script: %s\n", result);
exit(1);
}
/* Print (normal) result if non-empty; we'll skip handling encodings for now */
if (strlen(result)) {
printf("%s\n", result);
}
/* Clean up */
Tcl_DeleteInterp(interp);
exit(0);
}
This c wrapper is working fine for me and gives correct results.
Now I want to create a dll file, so that if i include that dll to any program that supports dll, it should be able to use this addition functionality of the above tcl code. Can anybody please tell me the way i can do it. Please help me. I am new to this dll concept.
In order to create the .dll you'll have to use something like Visual Studio and C or C++ to create the .dll (there are lots of other tools out there that can create .dll files but VS is easy to get hold of and to use.) So in VS create a new project, this needs to be a C++ WIN32 project. Select the DLL application type and the Export Symbols additional option.
VS will create a basic .dll that you can then amend to do what you want. I short I'd look at putting the creating/destruction of the intrepter into the dllmain:
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
Tcl_FindExecutable(NULL);
interp = Tcl_CreateInterp();
}
case DLL_THREAD_ATTACH:
break ;
case DLL_THREAD_DETACH:
break ;
case DLL_PROCESS_DETACH:
{
Tcl_DeleteInterp(interp);
break;
}
}
return TRUE;
}
and then create functions exported by the .dll that make use of the interpreter. If you aren't familiar with the concept of shared libaries then I'd suggest spending a little time reading up on them, try here and here for some background reading.