how to use serial port in UDK using windows DLL and DLLBind directive?
- by Shayan Abbas
I want to use serial port in UDK, For that purpose i use a windows DLL and DLLBind directive. I have a thread in windows DLL for serial port data recieve event. My problem is: this thread doesn't work properly. Please Help me.
below is my code
SerialPortDLL Code:
// SerialPortDLL.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#include "Cport.h"
extern "C"
{
// This is an example of an exported variable
//SERIALPORTDLL_API int nSerialPortDLL=0;
// This is an example of an exported function.
//SERIALPORTDLL_API int fnSerialPortDLL(void)
//{
// return 42;
//}
CPort *sp;
__declspec(dllexport) void Open(wchar_t* portName)
{
sp = new CPort(portName);
//MessageBox(0,L"ha ha!!!",L"ha ha",0);
//MessageBox(0,portName,L"ha ha",0);
}
__declspec(dllexport) void Close()
{
sp->Close();
MessageBox(0,L"ha ha!!!",L"ha ha",0);
}
__declspec(dllexport) wchar_t *GetData()
{
return sp->GetData();
}
__declspec(dllexport) unsigned int GetDSR()
{
return sp->getDSR();
}
__declspec(dllexport) unsigned int GetCTS()
{
return sp->getCTS();
}
__declspec(dllexport) unsigned int GetRing()
{
return sp->getRing();
}
}
CPort class code:
#include "stdafx.h"
#include "CPort.h"
#include "Serial.h"
CSerial serial;
HANDLE HandleOfThread;
LONG lLastError = ERROR_SUCCESS;
bool fContinue = true;
HANDLE hevtOverlapped;
HANDLE hevtStop;
OVERLAPPED ov = {0};
//char szBuffer[101] = "";
wchar_t *szBuffer = L"";
wchar_t *data = L"";
DWORD WINAPI ThreadHandler( LPVOID lpParam )
{
// Keep reading data, until an EOF (CTRL-Z) has been received
do
{
MessageBox(0,L"ga ga!!!",L"ga ga",0);
//Sleep(10);
// Wait for an event
lLastError = serial.WaitEvent(&ov);
if (lLastError != ERROR_SUCCESS)
{
//LOG( " Unable to wait for a COM-port event" );
}
// Setup array of handles in which we are interested
HANDLE ahWait[2];
ahWait[0] = hevtOverlapped;
ahWait[1] = hevtStop;
// Wait until something happens
switch (::WaitForMultipleObjects(sizeof(ahWait)/sizeof(*ahWait),ahWait,FALSE,INFINITE))
{
case WAIT_OBJECT_0:
{
// Save event
const CSerial::EEvent eEvent = serial.GetEventType();
// Handle break event
if (eEvent & CSerial::EEventBreak)
{
//LOG( " ### BREAK received ###" );
}
// Handle CTS event
if (eEvent & CSerial::EEventCTS)
{
//LOG( " ### Clear to send %s ###", serial.GetCTS() ? "on":"off" );
}
// Handle DSR event
if (eEvent & CSerial::EEventDSR)
{
//LOG( " ### Data set ready %s ###", serial.GetDSR() ? "on":"off" );
}
// Handle error event
if (eEvent & CSerial::EEventError)
{
switch (serial.GetError())
{
case CSerial::EErrorBreak: /*LOG( " Break condition" );*/ break;
case CSerial::EErrorFrame: /*LOG( " Framing error" );*/ break;
case CSerial::EErrorIOE: /*LOG( " IO device error" );*/ break;
case CSerial::EErrorMode: /*LOG( " Unsupported mode" );*/ break;
case CSerial::EErrorOverrun: /*LOG( " Buffer overrun" );*/ break;
case CSerial::EErrorRxOver: /*LOG( " Input buffer overflow" );*/ break;
case CSerial::EErrorParity: /*LOG( " Input parity error" );*/ break;
case CSerial::EErrorTxFull: /*LOG( " Output buffer full" );*/ break;
default: /*LOG( " Unknown" );*/ break;
}
}
// Handle ring event
if (eEvent & CSerial::EEventRing)
{
//LOG( " ### RING ###" );
}
// Handle RLSD/CD event
if (eEvent & CSerial::EEventRLSD)
{
//LOG( " ### RLSD/CD %s ###", serial.GetRLSD() ? "on" : "off" );
}
// Handle data receive event
if (eEvent & CSerial::EEventRecv)
{
// Read data, until there is nothing left
DWORD dwBytesRead = 0;
do
{
// Read data from the COM-port
lLastError = serial.Read(szBuffer,33,&dwBytesRead);
if (lLastError != ERROR_SUCCESS)
{
//LOG( "Unable to read from COM-port" );
}
if( dwBytesRead == 33 && szBuffer[0]=='$' )
{
// Finalize the data, so it is a valid string
szBuffer[dwBytesRead] = '\0';
////LOG( "\n%s\n", szBuffer );
data = szBuffer;
}
}
while (dwBytesRead > 0);
}
}
break;
case WAIT_OBJECT_0+1:
{
// Set the continue bit to false, so we'll exit
fContinue = false;
}
break;
default:
{
// Something went wrong
//LOG( "Error while calling WaitForMultipleObjects" );
}
break;
}
}
while (fContinue);
MessageBox(0,L"kka kk!!!",L"kka ga",0);
return 0;
}
CPort::CPort(wchar_t *portName)
{
// Attempt to open the serial port (COM2)
//lLastError = serial.Open(_T(portName),0,0,true);
lLastError = serial.Open(portName,0,0,true);
if (lLastError != ERROR_SUCCESS)
{
//LOG( "Unable to open COM-port" );
}
// Setup the serial port (115200,8N1, which is the default setting)
lLastError = serial.Setup(CSerial::EBaud115200,CSerial::EData8,CSerial::EParNone,CSerial::EStop1);
if (lLastError != ERROR_SUCCESS)
{
//LOG( "Unable to set COM-port setting" );
}
// Register only for the receive event
lLastError = serial.SetMask(CSerial::EEventBreak |
CSerial::EEventCTS |
CSerial::EEventDSR |
CSerial::EEventError |
CSerial::EEventRing |
CSerial::EEventRLSD |
CSerial::EEventRecv);
if (lLastError != ERROR_SUCCESS)
{
//LOG( "Unable to set COM-port event mask" );
}
// Use 'non-blocking' reads, because we don't know how many bytes
// will be received. This is normally the most convenient mode
// (and also the default mode for reading data).
lLastError = serial.SetupReadTimeouts(CSerial::EReadTimeoutNonblocking);
if (lLastError != ERROR_SUCCESS)
{
//LOG( "Unable to set COM-port read timeout" );
}
// Create a handle for the overlapped operations
hevtOverlapped = ::CreateEvent(0,TRUE,FALSE,0);;
if (hevtOverlapped == 0)
{
//LOG( "Unable to create manual-reset event for overlapped I/O" );
}
// Setup the overlapped structure
ov.hEvent = hevtOverlapped;
// Open the "STOP" handle
hevtStop = ::CreateEvent(0,TRUE,FALSE,_T("Overlapped_Stop_Event"));
if (hevtStop == 0)
{
//LOG( "Unable to create manual-reset event for stop event" );
}
HandleOfThread = CreateThread( NULL, 0, ThreadHandler, 0, 0, NULL);
}
CPort::~CPort()
{
//fContinue = false;
//CloseHandle( HandleOfThread );
//serial.Close();
}
void CPort::Close()
{
fContinue = false;
CloseHandle( HandleOfThread );
serial.Close();
}
wchar_t *CPort::GetData()
{
return data;
}
bool CPort::getCTS()
{
return serial.GetCTS();
}
bool CPort::getDSR()
{
return serial.GetDSR();
}
bool CPort::getRing()
{
return serial.GetRing();
}
Unreal Script Code:
class MyPlayerController extends GamePlayerController
DLLBind(SerialPortDLL);
dllimport final function Open(string portName);
dllimport final function Close();
dllimport final function string GetData();