源代码请从这里下载:http://www.cppblog.com/Files/dyj057/Midapexsoft.IO.SerialPort.rar,请使用VS2005打开.
我写的CAsyncSerialPort类是一个MFC的类,怎么才能使它在托管代码中使用呢?方法有两个:
l 把类的功能封装成DLL中的API,然后通过平台调用实现。这个方法我以前写过,就不说了,适合在.NET 1.0 或 1.1中使用。
l 使用C++/CLI把CAsyncSerialPort转换成一个托管类,然后供C#等代码使用,这个方法适合在.NET 2.0中使用,下面介绍这个方法。
下面写出步骤:
第一步:在VS2005中,使用C#创建一个包含串口通讯的接口,生成DLL组件。
第二步:创建一个C++/CLI的组件工程,一定要生成DLL的工程,不能是exe然后引入上面创建的接口DLL,实现一个SerialPortX类。
通过上面的方法,就把基于MFC的CAsyncSerialPort转化成了实现了ISerialPort接口的托管类SerialPortX。这个对于许多以前C++写的代码转到.NET 2.0中使用,都有借鉴意义。我还使用这个方法,把一个OPC Server的MFC实现,转换到了.NET 2.0,很好用的。^:^
最后,我使用SerialPortX在VS2005中写了一个串口通讯工具。
界面效果如下:
关键代码如下:
using System;
using System.IO.Ports;
namespace Midapexsoft.IO.Ports
{
/// <summary>
/// Interface of serial port
/// </summary>
public interface ISerialPort : IDisposable, Midapexsoft.IO.ITerminal
{
#region Property
string PortName
{
get;
set;
}
Parity Parity
{
get;
set;
}
int DataBits
{
get;
set;
}
StopBits StopBits
{
get;
set;
}
StandardBaudRate BaudRate
{
get;
set;
}
Handshake HandShake
{
get;
set;
}
#endregion
}
/// <summary>
/// Standard baud rate setting
/// </summary>
public enum StandardBaudRate
{
R110 = 110,
R300 = 300,
R600 = 600,
R1200 = 1200,
R2400 = 2400,
R4800 = 4800,
R9600 = 9600,
R14400 = 14400,
R19200 = 19200,
R38400 = 38400,
R57600 = 57600,
R76800 = 76800,
R115200 = 115200
};
}
//SerialPortX.h
#pragma once
#include "AsyncSerialPort.h"
#include "RuntimeException.h"
#include "SerialPortX.h"
#include "RuntimeException.h"
using namespace System;
using namespace System::Collections;
class CSerialPortObserver;
namespace Midapexsoft
{
namespace IO
{
namespace Port
{
public ref class SerialPortX: public IStartable, public ISerialPort
{
public:
SerialPortX(void);
~SerialPortX(void);
virtual void Stop();
virtual void SerialPortX::Start();
virtual void Write(array<byte> ^ data);
virtual event BytesEventHandler^ OnWriteData
{
void add(BytesEventHandler^ value)
{
writeDataHandler += value;
}
void remove(BytesEventHandler^ value)
{
writeDataHandler -= value;
}
void raise(Object^ sender, BytesEventArgs^ args)
{
if(writeDataHandler!=nullptr)
{
//writeDataHandler->BeginInvoke(sender, args,nullptr,nullptr);
writeDataHandler(sender,args);
}
}
}
virtual event BytesEventHandler^ OnReadData
{
void add(BytesEventHandler^ value)
{
readDataHandler += value;
}
void remove(BytesEventHandler^ value)
{
readDataHandler -= value;
}
void raise(Object^ sender, BytesEventArgs^ args)
{
if(readDataHandler!=nullptr)
{
//readDataHandler->BeginInvoke(sender, args,nullptr,nullptr);
readDataHandler(sender,args);
}
}
}
virtual event MessageEventHandler^ OnError
{
void add(MessageEventHandler^ value)
{
errorHandler += value;
}
void remove(MessageEventHandler^ value)
{
errorHandler -= value;
}
void raise(Object^ sender, MessageEventArgs^ args)
{
if(errorHandler!=nullptr)
{
//errorHandler->BeginInvoke(sender, args,nullptr,nullptr);
errorHandler(sender,args);
}
}
}
property String^ PortName
{
virtual String^ get() { return name;}
virtual void set(String^ newName)
{
//Get port number
int portNumberIndex = newName->IndexOf("COM");
if(portNumberIndex!=0)
{
throw gcnew Exception("Bad Port Name");
}
String^ portNumberS = newName->Substring(3);
portNumber = Convert::ToByte(portNumberS);
name= newName;
}
}
property Parity PortParity
{
virtual Parity get() { return parity;}
virtual void set(Parity parity)
{
try
{
if(IsOpen)
{
Hashtable^ parityTable = gcnew Hashtable();
parityTable->Add(L"None", 2);
parityTable->Add(L"Odd",3);
parityTable->Add(L"Even",gcnew int(0) );
parityTable->Add(L"Mark",1);
parityTable->Add(L"Space",4);
int parityMothord = (int) parityTable[parity.ToString()];
port->SetParity((CSerialPort::Parity)parityMothord);
}
this->parity = parity;
}
catch (CRuntimeException* e)
{
String^ info = gcnew String((LPCTSTR)e->GetErrorMessage());
throw gcnew Exception( info );
e->Delete();
}
}
}
property byte DataBytes
{
virtual byte get() { return dataBytes;}
virtual void set(byte dataBytes)
{
if(IsOpen)
{
port->SetDataBytes(dataBytes);
}
this->dataBytes = dataBytes;
}
}
property bool IsOpen
{
virtual bool get() { return port->IsOpen() != 0;}
}
property StopBits PortStopBits
{
virtual StopBits get() { return stopBits; }
virtual void set(StopBits stopBits)
{
try
{
if(IsOpen)
{
port->SetStopBits((CSerialPort::StopBits)(int)stopBits);
}
this->stopBits = stopBits;
}
catch (CRuntimeException* e)
{
String^ info = gcnew String((LPCTSTR)e->GetErrorMessage());
throw gcnew Exception( info );
e->Delete();
}
}
}
property StandardBaudRate BaudRate
{
virtual StandardBaudRate get() { return this->baudRate; }
virtual void set(StandardBaudRate newBaudRate)
{
try
{
if(IsOpen)
{
int baud = (int)newBaudRate;
port->SetBaud(baud);
}
this->baudRate = newBaudRate;
}
catch (CRuntimeException* e)
{
String^ info = gcnew String((LPCTSTR)e->GetErrorMessage());
throw gcnew Exception( info );
e->Delete();
}
}
}
property Handshake PortHandShake
{
virtual Handshake get() { return this->handshake;}
virtual void set( Handshake newHandShake)
{
try
{
if(IsOpen)
{
Hashtable ^ handshakeTable = gcnew Hashtable();
handshakeTable->Add("None",gcnew int(0));
handshakeTable->Add("XonXoff",5);
handshakeTable->Add("CtsRts",1);
handshakeTable->Add("DsrDtr",4);
//Handshake
int handshake = (int)handshakeTable[ newHandShake.ToString() ];
port->SetFlowControl((CSerialPort::FlowControl)handshake);
}
this->handshake = newHandShake;
}
catch (CRuntimeException* e)
{
String^ info = gcnew String((LPCTSTR)e->GetErrorMessage());
throw gcnew Exception( info );
e->Delete();
}
}
}
property bool CanStart
{
virtual bool get() { return canStart;}
virtual void set(bool canStart) { this->canStart = canStart; }
}
property bool IsRun
{
virtual bool get() { return isRun;}
}
virtual event EventHandler<StartableArgs^>^ OnStartableStatueChange
{
void add(EventHandler<StartableArgs^>^ value)
{
statusChangeHandler+= value;
}
void remove(EventHandler<StartableArgs^>^ value)
{
statusChangeHandler -= value;
}
void raise(Object^ sender, StartableArgs^ args)
{
if(statusChangeHandler!=nullptr)
{
statusChangeHandler->BeginInvoke(sender,args,nullptr,nullptr);
}
}
}
internal:
void OnPortWriteData(array<Byte>^ data)
{
OnWriteData(this, gcnew BytesEventArgs(data));
}
void OnPortReceiveData(array<Byte>^ data)
{
OnReadData(this, gcnew BytesEventArgs(data));
}
void ReportError(String^ errorMessage)
{
OnError(this, gcnew MessageEventArgs(errorMessage));
}
void SetRunStatus(bool isRun)
{
this->isRun = isRun;
OnStartableStatueChange(this, gcnew StartableArgs(this));
}
private:
CAsyncSerialPort* port;
CSerialPortObserver* observer;
private:
String^ name;
Parity parity;
byte dataBytes;
StandardBaudRate baudRate;
Handshake handshake;
StopBits stopBits;
byte portNumber;
bool canStart;
bool isRun;
BytesEventHandler^ writeDataHandler;
BytesEventHandler^ readDataHandler;
MessageEventHandler^ errorHandler;
EventHandler<StartableArgs^>^ statusChangeHandler;
};
}
}
}
posted on 2007-08-24 09:28
天下无双 阅读(2231)
评论(1) 编辑 收藏 引用 所属分类:
C/C++