Hello Everyone ,
I'am new to OOP and QT and i'm trying to write a simple chat program (client , server) with winsockets.
I Have an error which i don't seem to understand :

this is my code so far :

#include "pmessenger.h"
#include "ui_pmessenger.h"
#include <QMessageBox>
#include <winsock2.h>
SOCKET s;
PMessenger::PMessenger(QWidget *parent) : QMainWindow(parent), ui(new Ui::PMessenger)
{
    ui->setupUi(this);
    WSADATA wsadata;
    if(WSAStartup(MAKEWORD(2,2),&wsadata)!=0)
    {
         QMessageBox::critical(this,"Error","Winsock Startup Failed",0,0);
         this->close();
    }
    s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(s==INVALID_SOCKET)
    {
          QMessageBox::critical(this,"Error","Socket Creation Faild",0,0);
          WSACleanup();
          this->close();
    }
    SOCKADDR_IN server;
    server.sin_family = AF_INET;
    server.sin_port = htons(7676);
    server.sin_addr.s_addr = inet_addr("my ip is here :D");
    if(::connect(s,(sockaddr*)&server,sizeof(server))!=0)
    {
          QMessageBox::critical(this,"Error","Can't Connect",0,0);
          WSACleanup();
          this->close();
    }
    CreateThread(NULL,0,ServerMsgThread,(LPVOID)s,0,0); // the problem is in this line :(
}

PMessenger::~PMessenger()
{
    delete ui;
}

void PMessenger::on_pushButton_clicked()
{
    QString msg = ui->plainTextEdit_2->toPlainText();
    send(s,(const char *)msg.data(),4096,0);
}

void PMessenger::AddMessege(char msg[4096])
{
    ui->plainTextEdit->appendPlainText(msg);
}

DWORD PMessenger::ServerMsgThread(LPVOID pParam)
{
      SOCKET Cs = (SOCKET) pParam;
      char data[4096];
      while(1)
      {
           if(recv(Cs,data,1024,0)>0)
               AddMessege(data);
      }
      return 0;
}

I Get the following error :

..\PMessenger\pmessenger.cpp:32: error: argument of type 'DWORD (PMessenger:: )(void*)' does not match 'DWORD (*)(void*)'

Any help would be greatly appreciated (i really don't want to move to wxWidgets because of that error)

Thanks

Recommended Answers

All 8 Replies

CreateThread doesn't take a pointer to a class's method, let's read the error message together:
Your argument type: 'DWORD (PMessenger:: )(void*)'
Expected arg type: 'DWORD (*)(void*)'

So CreateThread is expecting a pointer to a function that returns a DWORD and takes void* as argument. There are several ways to 'beat' this problem, because you cannot simply cast your function to a DWORD (*)(void*).

You can use a 3rd party library like 'boost', which allows you to use pointers to member functions to start a thread.
You can create a small 'wrapper' function like this:

DWORD start_ServerMsgThread( LPVOID param )
{
   PMessenger* pMsg = static_cast<PMessenger*>( param );
   pMsg->ServerMsgThread();
}

And start the thread like:

CreateThread( NULL, 0, &start_ServerMsgThread, static_cast<LPVOID>(this), 0, 0);

You hand over the SOCKET to ServerMsgThread, but you can just store this as a private member variable and access it from ServerMsgThread.
If you don't want to do this, you can create a structure with 2 members:

struct StartThreadStruct {
  SOCKET s;
  PMessenger* pMsg;
};

Allocate this, hand it over to CreateThread and from start_ServerMsgThread pass it to ServerMsgThread and access the SOCKET from there.

I hope that helps.

why using Windows thing in QT, I mean QT is designed to be Xplatform and using windoish stuffs limits the very purpose. If you plan to use it in windows then go for Win32 API, or stay away from windowing and do it QT way :)

Having said so, I suggest Zetcode QT tutorial as one of Good start

@thelamb thanks a lot man , you really made my day , solved :D

@evstevemd you know what , you make a lot of sense , i mean it was very stupid of me to learn an Xplatform gui library then use windows stuff in the rest of the program :D
Oh and thanks for the tutorial seems great but do you know a QT network tutorial , coz the only i found was in german and the links were dead , Thanks. :)

@thelamb , i get an error when i tried to implement your idea at this line :
CreateThread(NULL,0,&ServerMsgThread,static_cast<LPVOID>(w),0,0);
Error : invalid static_cast from type 'PMessenger' to type 'void*'
:S

That's my code so far ,

#include <QtGui/QApplication>
#include "pmessenger.h"
#include "ui_pmessenger.h"
#include<winsock2.h>
#include<QMessageBox>
DWORD WINAPI ServerMsgThread(LPVOID pParam);
SOCKET s;
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    PMessenger w;
    w.show();
    WSADATA wsadata;
    if(WSAStartup(MAKEWORD(2,2),&wsadata)!=0)
    {
         QMessageBox::critical(0,"Error","Winsock Startup Failed",0,0);
         return 0;
    }
    s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(s==INVALID_SOCKET)
    {
          QMessageBox::critical(0,"Error","Socket Creation Faild",0,0);
          WSACleanup();
          return 0;
    }
    SOCKADDR_IN server;
    server.sin_family = AF_INET;
    server.sin_port = htons(7676);
    server.sin_addr.s_addr = inet_addr("41.238.115.48");
    if(::connect(s,(sockaddr*)&server,sizeof(server))!=0)
    {
          QMessageBox::critical(0,"Error","Can't Connect",0,0);
          WSACleanup();
          return 0;
    }
    CreateThread(NULL,0,&ServerMsgThread,static_cast<LPVOID>(w),0,0);
    return a.exec();
}

DWORD WINAPI ServerMsgThread(LPVOID pParam)
{
      PMessenger *ww = static_cast<PMessenger*>(pParam);
      char data[4096];
      while(1)
      {
           if(recv(s,data,1024,0)>0)
               ww->AddMessege(data);
      }
      return 0;
}

void PMessenger::on_pushButton_clicked()
{
    QString msg =  ui->plainTextEdit_2->toPlainText();
    send(s,(const char *)msg.data(),4096,0);
}

If that advice is good then stop what you are doing :)
Here are good resources but RTM is important!
1. Get acquainted with TCP/IP and sockets in general
2. Get the basics of QT after C++ of course!

Grab QT Book and get head up with the QT Network tutorial. Also QT site have got examples. Please surf through developer section

Stop trying to walk before crawl ;)

:D I Already did , and nearly finished the program in QT Sockets instead of WinSockets
Thanks a lot man.

:D I Already did , and nearly finished the program in QT Sockets instead of WinSockets
Thanks a lot man.

You are welcome

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.