Trying to make a thread

T

The Beast

I'm trying to create a thread to write to the serial port and I keep
getting an odd error

cannot convert parameter 3 from 'unsigned long (void *)' to 'unsigned
long (__stdcall *)(void *)'

and it points to the CreateThread call. Here is my class, why is it
doing this and how can I fix it?

<TxdRxd.h>

class TxdRxd
{
CString TempData;
DCB dcb;
DWORD NumBytes, BaudRate, ModemStatus;
BYTE Byte;
HANDLE PortHandle;
int Wait, DataLength;
CString ComPort;

public:

TxdRxd ();
TxdRxd (DWORD NewBaudRate);
~TxdRxd();
bool Transmit (CString PortSpecifier, CString Data);
bool Transmit (CString PortSpecifier, CString Data, DWORD
NewBaudRate);
int Receive (CString PortSpecifier, CString &Data);
int Receive (CString PortSpecifier, CString &Data, DWORD
NewBaudRate);
void SetBaud (DWORD NewBaudRate);
void CALLBACK EXPORT TimerProc (HWND hWnd,UINT nMsg,UINT
nIDEvent,DWORD dwTime);
DWORD WINAPI ThreadProc (LPVOID lpParam);

};

<TxdRxd.cpp>

#include "stdafx.h"
#include <process.h>
#include "TxdRxd.h"

TxdRxd::TxdRxd ()
{
BaudRate = CBR_9600;
}

TxdRxd::TxdRxd (DWORD NewBaudRate)
{
switch (NewBaudRate)
{
case 110:
BaudRate = CBR_110;
break;
case 300:
BaudRate = CBR_300;
break;
case 600:
BaudRate = CBR_600;
break;
case 1200:
BaudRate = CBR_1200;
break;
case 2400:
BaudRate = CBR_2400;
break;
case 4800:
BaudRate = CBR_4800;
break;
case 9600:
BaudRate = CBR_9600;
break;
case 14400:
BaudRate = CBR_14400;
break;
case 19200:
BaudRate = CBR_19200;
break;
case 38400:
BaudRate = CBR_38400;
break;
case 56000:
BaudRate = CBR_56000;
break;
case 57600:
BaudRate = CBR_57600;
break;
case 115200:
BaudRate = CBR_115200;
break;
case 128000:
BaudRate = CBR_128000;
break;
case 256000:
BaudRate = CBR_256000;
break;
}
}

TxdRxd::~TxdRxd()
{
}

bool TxdRxd::Transmit (CString PortSpecifier, CString Data)
{
Data = Data + char(0x03);
PortHandle = CreateFile(PortSpecifier, GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, 0, NULL);
DataLength = strlen(Data);

if (!GetCommState(PortHandle,&dcb))
{
return false;
}

dcb.BaudRate = BaudRate; //Set Baud Rate
dcb.ByteSize = 8; //8 data bits
dcb.Parity = NOPARITY; //no parity
dcb.StopBits = ONESTOPBIT; //1 stop

if (!SetCommState(PortHandle,&dcb)) return false;

bool retVal =
WriteFile(PortHandle,Data,DataLength,&NumBytes,NULL);

CloseHandle(PortHandle); //close the handle

return retVal;
}


bool TxdRxd::Transmit (CString PortSpecifier, CString Data, DWORD
NewBaudRate)
{
Data = Data + char(0x03);
PortHandle = CreateFile(PortSpecifier, GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, 0, NULL);
DataLength = strlen(Data);

switch (NewBaudRate)
{
case 110:
BaudRate = CBR_110;
break;
case 300:
BaudRate = CBR_300;
break;
case 600:
BaudRate = CBR_600;
break;
case 1200:
BaudRate = CBR_1200;
break;
case 2400:
BaudRate = CBR_2400;
break;
case 4800:
BaudRate = CBR_4800;
break;
case 9600:
BaudRate = CBR_9600;
break;
case 14400:
BaudRate = CBR_14400;
break;
case 19200:
BaudRate = CBR_19200;
break;
case 38400:
BaudRate = CBR_38400;
break;
case 56000:
BaudRate = CBR_56000;
break;
case 57600:
BaudRate = CBR_57600;
break;
case 115200:
BaudRate = CBR_115200;
break;
case 128000:
BaudRate = CBR_128000;
break;
case 256000:
BaudRate = CBR_256000;
break;
}

if (!GetCommState(PortHandle,&dcb))
{
return false;
}

dcb.BaudRate = BaudRate; //Set Baud Rate
dcb.ByteSize = 8; //8 data bits
dcb.Parity = NOPARITY; //no parity
dcb.StopBits = ONESTOPBIT; //1 stop

if (!SetCommState(PortHandle,&dcb)) return false;

bool retVal =
WriteFile(PortHandle,Data,DataLength,&NumBytes,NULL);

CloseHandle(PortHandle); //close the handle

return retVal;
}

void CALLBACK EXPORT TxdRxd::TimerProc(
HWND hWnd, // handle of CWnd that called SetTimer
UINT nMsg, // WM_TIMER
UINT nIDEvent, // timer identification
DWORD dwTime // system time
)
{
Wait = -1;
}

DWORD WINAPI TxdRxd::ThreadProc (LPVOID lpParameter)
{
PortHandle = CreateFile(ComPort, GENERIC_READ, 0, NULL,
OPEN_EXISTING, 0, NULL);

if (!GetCommState(PortHandle,&dcb))
{
TempData = "Port Could Not Be Opened";
return 1;
}

dcb.BaudRate = BaudRate; //Set Baud Rate
dcb.ByteSize = 8; //8 data bits
dcb.Parity = NOPARITY; //no parity
dcb.StopBits = ONESTOPBIT; //1 stop

if (!SetCommState(PortHandle,&dcb))
{
TempData = "Port Could Not Be Opened";
return 1;
}

SetCommMask (PortHandle, EV_RXCHAR | EV_ERR); //receive
character event
WaitCommEvent (PortHandle, &ModemStatus, 0); //wait for
character

if (ModemStatus & EV_RXCHAR)
{
ReadFile(PortHandle, &Byte, 1, &NumBytes, 0); //read
1
Wait = 1;
}
else if (ModemStatus & EV_ERR)
{
TempData = "COM Error";
return 2;
}

CloseHandle(PortHandle);
return 0;
}

int TxdRxd::Receive (CString PortSpecifier, CString &Data)
{
int Timer;
DWORD ThreadID;
HANDLE ThreadHandle;
void* lpParameter;

bool Ready = TRUE;
Data.Delete(0,1000);

Wait = 0;
while (Ready)
{
ThreadHandle = CreateThread(NULL, 0, ThreadProc, NULL,
0, &ThreadID);

Timer = SetTimer(NULL, NULL, 3000, NULL);

while (Wait == 0)
{}

if (Wait == 1)
{
if (Byte == 0x03) Ready = FALSE;
else Data = Data + char(Byte);
KillTimer(NULL, Timer);
}
else if (Wait == -1)
{
Ready = FALSE;
MessageBox(NULL, "Timed Out", "ERROR", MB_OK);
}
}
return 0;
}

int TxdRxd::Receive (CString PortSpecifier, CString &Data, DWORD
NewBaudRate)
{
return 1;
}

void TxdRxd::SetBaud (DWORD NewBaudRate)
{
switch (NewBaudRate)
{
case 110:
BaudRate = CBR_110;
break;
case 300:
BaudRate = CBR_300;
break;
case 600:
BaudRate = CBR_600;
break;
case 1200:
BaudRate = CBR_1200;
break;
case 2400:
BaudRate = CBR_2400;
break;
case 4800:
BaudRate = CBR_4800;
break;
case 9600:
BaudRate = CBR_9600;
break;
case 14400:
BaudRate = CBR_14400;
break;
case 19200:
BaudRate = CBR_19200;
break;
case 38400:
BaudRate = CBR_38400;
break;
case 56000:
BaudRate = CBR_56000;
break;
case 57600:
BaudRate = CBR_57600;
break;
case 115200:
BaudRate = CBR_115200;
break;
case 128000:
BaudRate = CBR_128000;
break;
case 256000:
BaudRate = CBR_256000;
break;
}

}
 
V

Victor Bazarov

The said:
I'm trying to create a thread to write to the serial port and I keep
getting an odd error

cannot convert parameter 3 from 'unsigned long (void *)' to 'unsigned
long (__stdcall *)(void *)'

and it points to the CreateThread call. Here is my class, why is it
doing this and how can I fix it?

C++ has no function CreateThread, so you're much better off asking in
a newsgroup where it is on topic (like your platform newsgroup, e.g.).
From the language point of view, it seems that you're trying to use
a non-static member function as a thread procedure. That's not allowed.
Make your member function static and proceed from there.

Victor
 
M

Mike Wahler

The Beast said:
I'm trying to create a thread to write to the serial port and I keep
getting an odd error

cannot convert parameter 3 from 'unsigned long (void *)' to 'unsigned
long (__stdcall *)(void *)'

and it points to the CreateThread call. Here is my class, why is it
doing this and how can I fix it?

Despite all the nonstandard Microsoft trappings, the problem is
still evident. You're trying to pass the address of a member
function as a parameter which specifies the address of a nonmember
function. This issue is addressed in the C++ FAQ:
http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.2

You also might want to check with the folks at newsgruop
'comp.os.ms-windows.programmer.win32' for suggestions about
the best way to approach this in a Windows environment (preferred
idioms, potential problems, etc.).

(You may also need to deal with the '__stdcall' issue, but that's
a Windows issue, not topical here).

-Mike
 
T

The Beast

Thank you! I tried making it static and it then denied me access to
the member variables. I'll try a C++ in windows forum, but thank you
anyway!

The Beast
 
T

The Beast

Thank you for your help! The forum you suggested does indeed look
helpful!

The Beast
 
L

LNK2005

Just wanted to add that the void* parameter to ThreadProc() is your true
friend;-)

Make two ThreadProc() methods:
static DWORD WINAPI ThreadProc (LPVOID lpParam);
DWORD ThreadProc ();

When calling CreateThread(), pass the this pointer as user data
(lpParameter). In the static ThreadProc(), cast lpParam back to TxdRxd* and
call the non-static ThreadProc() through that pointer. Solves the problem of
member variable access.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top