哪位高手能帮我写个com口的小程序啊! 一个很简单的东西,可是我什么都不会!从com口发送一个控制数据(最多三字节)然后要求得到回应!哪个高手可以帮我一下啊!具体qq上谈吧!qq:32428975 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 // 设置串口超时BOOL SetTimeOut(DWORD ReadIntervalTimeout, DWORD ReadTotalTimeoutMultiplier, DWORD ReadTotalTimeoutConstant){ COMMTIMEOUTS timeouts; GetCommTimeouts(m_gphdCom,&timeouts); timeouts.ReadIntervalTimeout=ReadIntervalTimeout; timeouts.ReadTotalTimeoutMultiplier=ReadTotalTimeoutMultiplier; timeouts.ReadTotalTimeoutConstant=ReadTotalTimeoutConstant; return SetCommTimeouts(m_gphdCom,&timeouts);}// 设置串口波特率BOOL set_baudrate(int baud_rate){ DCB dcb; BOOL fsuccess; fsuccess = GetCommState(m_gphdCom, &dcb); if (!fsuccess) { return FALSE; } dcb.BaudRate =baud_rate; dcb.ByteSize =8; //number of bits/byte, 4-8 dcb.Parity =NOPARITY; dcb.StopBits =ONESTOPBIT; //dcb.EvtChar=0x02; //dcb.fNull=TRUE; fsuccess=SetCommState(m_gphdCom, &dcb); if (!fsuccess) { return FALSE; } return TRUE;}// 打开串口extern "C" BOOL PASCAL Open(char *szPort,int Baud_rate, BOOL overlapped){ int retbuflength=0; if (overlapped) { //异步方式打开串口 memset( &READ_OS, 0, sizeof( OVERLAPPED ) ) ; memset( &WRITE_OS, 0, sizeof( OVERLAPPED ) ) ; READ_OS.hEvent = CreateEvent( NULL, // no security TRUE, // explicit reset req FALSE, // initial event reset NULL ) ; // no name if (READ_OS.hEvent == NULL) { return FALSE; } WRITE_OS.hEvent = CreateEvent( NULL, // no security TRUE, // explicit reset req FALSE, // initial event reset NULL ) ; // no name if (NULL == WRITE_OS.hEvent) { CloseHandle( READ_OS.hEvent ) ; return FALSE; } m_gphdCom=CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, // exclusive access NULL, // no security attrs OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL| FILE_FLAG_OVERLAPPED, // overlapped I/O NULL ); olap=TRUE; } //同步方式打开串口 else { m_gphdCom=CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, // exclusive access NULL, // no security attrs OPEN_EXISTING, 0, //is overlapped or no NULL ); } if (m_gphdCom==(HANDLE) -1) { DWORD RR=GetLastError(); CloseHandle(m_gphdCom) ; if (olap) { CloseHandle( READ_OS.hEvent ) ; CloseHandle( WRITE_OS.hEvent ) ; } fCOMMOpened=0; olap=FALSE; return FALSE; } set_baudrate(Baud_rate); fCOMMOpened=1; SetupComm(m_gphdCom,11520,2048); PurgeComm(m_gphdCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ) ; SetCommMask(m_gphdCom,EV_RXCHAR/* EV_RXFLAG*/ ); //set time out SetTimeOut(10,50,100); return TRUE;}// 关闭串口extern "C" BOOL PASCAL Close(){ if (fCOMMOpened==1) { fCOMMOpened=0; CloseHandle(m_gphdCom) ; olap=FALSE; if (olap) { CloseHandle( READ_OS.hEvent ) ; CloseHandle( WRITE_OS.hEvent ) ; } return TRUE; } return FALSE; } // 写串口extern "C" BOOL PASCAL Write(BYTE *buf,int buflen){ BOOL fWriteStat; DWORD dwErrorFlags; DWORD dwError; COMSTAT ComStat; char szError[ 10 ] ; DWORD ret; if (fCOMMOpened==0) { return FALSE;//串口未打开 } ret=0; if (olap) { fWriteStat = WriteFile(m_gphdCom,buf,buflen,&ret, &WRITE_OS ) ; if (!fWriteStat) { if ((dwError=GetLastError()) == ERROR_IO_PENDING) { while (!GetOverlappedResult(m_gphdCom,&WRITE_OS,&ret, TRUE )) { dwError = GetLastError(); if(dwError == ERROR_IO_INCOMPLETE) { OutputDebugString("write io pending"); continue; } else { //an error occurred, try to recover wsprintf( szError, "\n\r <CE-%u>", dwError ) ; OutputDebugString(szError); ClearCommError(m_gphdCom, &dwErrorFlags, &ComStat ) ; if (dwErrorFlags > 0) { wsprintf( szError, "\n\r <CE-%u>",dwErrorFlags ) ; OutputDebugString(szError); } break; } } } else { // some other error occurred wsprintf( szError, "\n\r <CE-%u>", dwError ) ; OutputDebugString(szError); ClearCommError(m_gphdCom,&dwErrorFlags,&ComStat ) ; if (dwErrorFlags>0) { wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags) ; OutputDebugString(szError); } return FALSE; } } } else { fWriteStat = WriteFile(m_gphdCom, buf,(DWORD)buflen,&ret, NULL); if (!fWriteStat) { if(GetLastError() == ERROR_IO_PENDING) { dwError = GetLastError(); // an error occurred, try to recover wsprintf( szError, "\n\r <CE-%u>", dwError ) ; OutputDebugString(szError); ClearCommError(m_gphdCom, &dwErrorFlags, &ComStat ) ; if (dwErrorFlags >0) { wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ; OutputDebugString(szError); } } else { // some other error occurred ClearCommError(m_gphdCom, &dwErrorFlags, &ComStat ) ; if (dwErrorFlags > 0) { wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ; OutputDebugString(szError); } return FALSE; } } } return TRUE;}// 读串口extern "C" BOOL PASCAL Read(BYTE *buf,int nMaxLength){ BOOL fReadStat ; COMSTAT ComStat; DWORD dwErrorFlags; DWORD dwLength; DWORD dwError; char szError[ 10 ]; if (fCOMMOpened==0) { return FALSE; //串口未打开 } // only try to read number of bytes in queue ClearCommError(m_gphdCom, &dwErrorFlags, &ComStat) ; //dwLength = min( (DWORD) nMaxLength, ComStat.cbInQue ) ; dwLength=nMaxLength; if (dwLength > 0) { if (olap==TRUE) { fReadStat = ReadFile(m_gphdCom,buf, dwLength, &dwLength,&READ_OS) ; if (!fReadStat) { if (GetLastError() == ERROR_IO_PENDING) { OutputDebugString("\n\rIO Pending"); while(!GetOverlappedResult(m_gphdCom, &READ_OS, &dwLength, TRUE )) { dwError = GetLastError(); if(dwError == ERROR_IO_INCOMPLETE) continue; else { // an error occurred, try to recover ClearCommError(m_gphdCom,&dwErrorFlags, &ComStat ) ; break; } } } else // end-----if (GetLastError() == ERROR_IO_PENDING) { // some other error occurred dwLength = 0 ; ClearCommError(m_gphdCom, &dwErrorFlags, &ComStat ) ; if (dwErrorFlags >0) { wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ; OutputDebugString(szError); } } } // end-----if (!fReadStat) } // end-----if (olap==TRUE) else { fReadStat = ReadFile( m_gphdCom,buf, dwLength, &dwLength, NULL ) ; if (!fReadStat) { dwError = GetLastError(); ClearCommError(m_gphdCom,&dwErrorFlags, &ComStat ) ; if (dwErrorFlags >0) { wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ; OutputDebugString(szError); } } } } return TRUE;}把我给你的这写函数自己组织一下就能解决你的问题了,自己写吧 兄弟,你为什么调用那么多PASCAL函数呢? 考..哥们...那是一种编译方式....我这是一个DLL中的代码.你可以不要extern "C" BOOL PASCAL Read(BYTE *buf,int nMaxLength)可以写成以下这样BOOL Read(BYTE *buf,int nMaxLength) 一个比较简单的COM此例子共有四个文件组成: 文件名 说明 Interface.h 接口类定义文件 Math.h和Math.cpp 实现类文件 Simple.cpp 主函数文件 这里用来当作COM的客户端 2.1 interface.h 文件#ifndef INTERFACE_H#define INTERFACE_H#include <unknwn.h>//{7C8027EA-A4ED-467c-B17E-1B51CE74AF57}static const GUID IID_ISimpleMath = { 0x7c8027ea, 0xa4ed, 0x467c, { 0xb1, 0x7e, 0x1b, 0x51, 0xce, 0x74, 0xaf, 0x57 } };//{CA3B37EA-E44A-49b8-9729-6E9222CAE84F}static const GUID IID_IAdvancedMath = { 0xca3b37ea, 0xe44a, 0x49b8, { 0x97, 0x29, 0x6e, 0x92, 0x22, 0xca, 0xe8, 0x4f } };interface ISimpleMath : public IUnknown{public: virtual int Add(int nOp1, int nOp2) = 0; virtual int Subtract(int nOp1, int nOp2) = 0; virtual int Multiply(int nOp1, int nOp2) = 0; virtual int Divide(int nOp1, int nOp2) = 0;};interface IAdvancedMath : public IUnknown{public: virtual int Factorial(int nOp1) = 0; virtual int Fabonacci(int nOp1) = 0;};#endif 此文件首先 #include <unknwn.h> 将 IUnknown 接口定义文件包括进来。接下来定义了两个接口,GUID(Globally Unique Identifier全局唯一标识符)它能保证时间及空间上的唯一。ISmipleMath接口里定义了四个方法,而IAdvancedMath接口里定义了二个方法。这些方法都是虚函数,而整个 ISmipleMath 与 IAdvancedMath 抽象类就作为二进制的接口。2.2 math.h文件 #include "interface.h"class CMath : public ISimpleMath, public IAdvancedMath{private: ULONG m_cRef;private: int calcFactorial(int nOp); int calcFabonacci(int nOp);public: //IUnknown Method STDMETHOD(QueryInterface)(REFIID riid, void **ppv); STDMETHOD_(ULONG, AddRef)(); STDMETHOD_(ULONG, Release)(); // ISimpleMath Method int Add(int nOp1, int nOp2); int Subtract(int nOp1, int nOp2); int Multiply(int nOp1, int nOp2); int Divide(int nOp1, int nOp2); // IAdvancedMath Method int Factorial(int nOp); int Fabonacci(int nOp);}; 此类为实现类,他实现了ISmipleMath和IAdvancedMath两个接口类(当然也可以只实现一个接口类)。请注意:m_cRef 是用来对象计数用的。当 m_cRef 为0组件对象应该自动删除。2.3 math.cpp文件 #include "interface.h"#include "math.h"STDMETHODIMP CMath::QueryInterface(REFIID riid, void **ppv){// 这里这是实现dynamic_cast的功能,但由于dynamic_cast与编译器相关。 if(riid == IID_ISimpleMath) *ppv = static_cast(this); else if(riid == IID_IAdvancedMath) *ppv = static_cast(this); else if(riid == IID_IUnknown) *ppv = static_cast(this); else { *ppv = 0; return E_NOINTERFACE; } reinterpret_cast(*ppv)->AddRef(); //这里要这样是因为引用计数是针对组件的 return S_OK;}STDMETHODIMP_(ULONG) CMath::AddRef(){ return ++m_cRef;}STDMETHODIMP_(ULONG) CMath::Release(){ ULONG res = --m_cRef; // 使用临时变量把修改后的引用计数值缓存起来 if(res == 0) // 因为在对象已经销毁后再引用这个对象的数据将是非法的 delete this; return res;}int CMath::Add(int nOp1, int nOp2){ return nOp1+nOp2;}int CMath::Subtract(int nOp1, int nOp2){ return nOp1 - nOp2;}int CMath::Multiply(int nOp1, int nOp2){ return nOp1 * nOp2;}int CMath::Divide(int nOp1, int nOp2){ return nOp1 / nOp2;}int CMath::calcFactorial(int nOp){ if(nOp <= 1) return 1; return nOp * calcFactorial(nOp - 1);}int CMath::Factorial(int nOp){ return calcFactorial(nOp);}int CMath::calcFabonacci(int nOp){ if(nOp <= 1) return 1; return calcFabonacci(nOp - 1) + calcFabonacci(nOp - 2);}int CMath::Fabonacci(int nOp){ return calcFabonacci(nOp);} CMath::CMath(){ m_cRef=0;} 此文件是CMath类定义文件。 simple.cpp文件 #include "math.h"#include <iostream>using namespace std;int main(int argc, char* argv[]){ ISimpleMath *pSimpleMath = NULL;//声明接口指针 IAdvancedMath *pAdvMath = NULL; //创建对象实例,我们暂时这样创建对象实例,COM有创建对象实例的机制 CMath *pMath = new CMath; //查询对象实现的接口ISimpleMath pMath->QueryInterface(IID_ISimpleMath, (void **)&pSimpleMath); if(pSimpleMath) cout << "10 + 4 = " << pSimpleMath->Add(10, 4) << endl; //查询对象实现的接口IAdvancedMath pSimpleMath->QueryInterface(IID_IAdvancedMath, (void **)&pAdvMath); if(pAdvMath) cout << "10 Fabonacci is " << pAdvMath->Fabonacci(10) << endl; pAdvMath->Release(); pSimpleMath->Release(); return 0;}此文件相当于客户端的代码,首先创建一个CMath对象,再根据此对象去查询所需要的接口,如果正确得到所需接口指针,再调用接口的方法,最后再将接口的释放掉。 如何用VC控制DirectUI做的界面按钮 LIST iterator类型的pit,后移问题 >_< 在线等,谢谢各位,嘻嘻 想换工作,不知道薪水应该什么水平 如何获取当前鼠标上的字符串内容?高分送? 关于GZIP格式解压缩HTTP数据包的问题,我使用ZLIB为什么必须先保存文件,内存解压缩出错 如何获取已知进程下的所有进程 如何动态创建DSN号,指定数据库驱动程序(access),创建数据库 很简单的问题(关于tree控件)100分阿 请问如何使用GDI+在简体系统下显示繁体BIG5码的文本? 求MFC大牛现身指导~~ 请问CtableCtrl的使用方法?(来者有分) 关于写com口
BOOL SetTimeOut(DWORD ReadIntervalTimeout,
DWORD ReadTotalTimeoutMultiplier,
DWORD ReadTotalTimeoutConstant)
{
COMMTIMEOUTS timeouts; GetCommTimeouts(m_gphdCom,&timeouts);
timeouts.ReadIntervalTimeout=ReadIntervalTimeout;
timeouts.ReadTotalTimeoutMultiplier=ReadTotalTimeoutMultiplier;
timeouts.ReadTotalTimeoutConstant=ReadTotalTimeoutConstant;
return SetCommTimeouts(m_gphdCom,&timeouts);
}// 设置串口波特率
BOOL set_baudrate(int baud_rate)
{
DCB dcb;
BOOL fsuccess;
fsuccess = GetCommState(m_gphdCom, &dcb);
if (!fsuccess)
{
return FALSE;
}
dcb.BaudRate =baud_rate;
dcb.ByteSize =8; //number of bits/byte, 4-8
dcb.Parity =NOPARITY;
dcb.StopBits =ONESTOPBIT;
//dcb.EvtChar=0x02;
//dcb.fNull=TRUE; fsuccess=SetCommState(m_gphdCom, &dcb);
if (!fsuccess)
{
return FALSE;
} return TRUE;
}// 打开串口
extern "C" BOOL PASCAL Open(char *szPort,int Baud_rate, BOOL overlapped)
{
int retbuflength=0;
if (overlapped)
{ //异步方式打开串口
memset( &READ_OS, 0, sizeof( OVERLAPPED ) ) ;
memset( &WRITE_OS, 0, sizeof( OVERLAPPED ) ) ; READ_OS.hEvent = CreateEvent( NULL, // no security
TRUE, // explicit reset req
FALSE, // initial event reset
NULL ) ; // no name
if (READ_OS.hEvent == NULL)
{
return FALSE;
}
WRITE_OS.hEvent = CreateEvent( NULL, // no security
TRUE, // explicit reset req
FALSE, // initial event reset
NULL ) ; // no name
if (NULL == WRITE_OS.hEvent)
{
CloseHandle( READ_OS.hEvent ) ;
return FALSE;
}
m_gphdCom=CreateFile( szPort, GENERIC_READ | GENERIC_WRITE,
0, // exclusive access
NULL, // no security attrs
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|
FILE_FLAG_OVERLAPPED, // overlapped I/O
NULL );
olap=TRUE;
} //同步方式打开串口
else
{
m_gphdCom=CreateFile( szPort, GENERIC_READ | GENERIC_WRITE,
0, // exclusive access
NULL, // no security attrs
OPEN_EXISTING,
0, //is overlapped or no
NULL );
}
if (m_gphdCom==(HANDLE) -1)
{
DWORD RR=GetLastError();
CloseHandle(m_gphdCom) ;
if (olap)
{
CloseHandle( READ_OS.hEvent ) ;
CloseHandle( WRITE_OS.hEvent ) ;
}
fCOMMOpened=0;
olap=FALSE;
return FALSE;
}
set_baudrate(Baud_rate);
fCOMMOpened=1;
SetupComm(m_gphdCom,11520,2048);
PurgeComm(m_gphdCom, PURGE_TXABORT | PURGE_RXABORT |
PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
SetCommMask(m_gphdCom,EV_RXCHAR/* EV_RXFLAG*/ );
//set time out
SetTimeOut(10,50,100);
return TRUE;
}// 关闭串口
extern "C" BOOL PASCAL Close()
{
if (fCOMMOpened==1)
{
fCOMMOpened=0;
CloseHandle(m_gphdCom) ;
olap=FALSE;
if (olap)
{
CloseHandle( READ_OS.hEvent ) ;
CloseHandle( WRITE_OS.hEvent ) ;
}
return TRUE;
}
return FALSE;
}
extern "C" BOOL PASCAL Write(BYTE *buf,int buflen)
{
BOOL fWriteStat;
DWORD dwErrorFlags;
DWORD dwError;
COMSTAT ComStat;
char szError[ 10 ] ;
DWORD ret; if (fCOMMOpened==0)
{
return FALSE;//串口未打开
}
ret=0;
if (olap)
{
fWriteStat = WriteFile(m_gphdCom,buf,buflen,&ret, &WRITE_OS ) ;
if (!fWriteStat)
{
if ((dwError=GetLastError()) == ERROR_IO_PENDING)
{
while (!GetOverlappedResult(m_gphdCom,&WRITE_OS,&ret, TRUE ))
{
dwError = GetLastError();
if(dwError == ERROR_IO_INCOMPLETE)
{
OutputDebugString("write io pending");
continue;
}
else
{
//an error occurred, try to recover
wsprintf( szError, "\n\r <CE-%u>", dwError ) ;
OutputDebugString(szError);
ClearCommError(m_gphdCom, &dwErrorFlags, &ComStat ) ;
if (dwErrorFlags > 0)
{
wsprintf( szError, "\n\r <CE-%u>",dwErrorFlags ) ;
OutputDebugString(szError);
}
break;
}
}
}
else
{
// some other error occurred
wsprintf( szError, "\n\r <CE-%u>", dwError ) ;
OutputDebugString(szError);
ClearCommError(m_gphdCom,&dwErrorFlags,&ComStat ) ;
if (dwErrorFlags>0)
{
wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags) ;
OutputDebugString(szError);
}
return FALSE;
}
}
}
else
{
fWriteStat = WriteFile(m_gphdCom, buf,(DWORD)buflen,&ret, NULL);
if (!fWriteStat)
{
if(GetLastError() == ERROR_IO_PENDING)
{
dwError = GetLastError();
// an error occurred, try to recover
wsprintf( szError, "\n\r <CE-%u>", dwError ) ;
OutputDebugString(szError);
ClearCommError(m_gphdCom, &dwErrorFlags, &ComStat ) ;
if (dwErrorFlags >0)
{
wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ;
OutputDebugString(szError);
}
}
else
{
// some other error occurred
ClearCommError(m_gphdCom, &dwErrorFlags, &ComStat ) ;
if (dwErrorFlags > 0)
{
wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ;
OutputDebugString(szError);
}
return FALSE;
}
}
}
return TRUE;
}// 读串口
extern "C" BOOL PASCAL Read(BYTE *buf,int nMaxLength)
{
BOOL fReadStat ;
COMSTAT ComStat;
DWORD dwErrorFlags;
DWORD dwLength;
DWORD dwError;
char szError[ 10 ];
if (fCOMMOpened==0)
{
return FALSE; //串口未打开
} // only try to read number of bytes in queue
ClearCommError(m_gphdCom, &dwErrorFlags, &ComStat) ;
//dwLength = min( (DWORD) nMaxLength, ComStat.cbInQue ) ;
dwLength=nMaxLength;
if (dwLength > 0)
{
if (olap==TRUE)
{
fReadStat = ReadFile(m_gphdCom,buf, dwLength, &dwLength,&READ_OS) ;
if (!fReadStat)
{
if (GetLastError() == ERROR_IO_PENDING)
{
OutputDebugString("\n\rIO Pending");
while(!GetOverlappedResult(m_gphdCom, &READ_OS,
&dwLength, TRUE ))
{
dwError = GetLastError();
if(dwError == ERROR_IO_INCOMPLETE) continue;
else
{
// an error occurred, try to recover
ClearCommError(m_gphdCom,&dwErrorFlags, &ComStat ) ;
break;
}
}
}
else // end-----if (GetLastError() == ERROR_IO_PENDING)
{
// some other error occurred
dwLength = 0 ;
ClearCommError(m_gphdCom, &dwErrorFlags, &ComStat ) ;
if (dwErrorFlags >0)
{
wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ;
OutputDebugString(szError);
}
}
} // end-----if (!fReadStat)
} // end-----if (olap==TRUE)
else
{
fReadStat = ReadFile( m_gphdCom,buf, dwLength, &dwLength, NULL ) ;
if (!fReadStat)
{
dwError = GetLastError();
ClearCommError(m_gphdCom,&dwErrorFlags, &ComStat ) ;
if (dwErrorFlags >0)
{
wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ;
OutputDebugString(szError);
}
}
}
} return TRUE;
}
把我给你的这写函数自己组织一下就能解决你的问题了,自己写吧
extern "C" BOOL PASCAL Read(BYTE *buf,int nMaxLength)可以写成以下这样
BOOL Read(BYTE *buf,int nMaxLength)
文件名 说明
Interface.h 接口类定义文件
Math.h和Math.cpp 实现类文件
Simple.cpp 主函数文件 这里用来当作COM的客户端 2.1 interface.h 文件
#ifndef INTERFACE_H
#define INTERFACE_H
#include <unknwn.h>//{7C8027EA-A4ED-467c-B17E-1B51CE74AF57}
static const GUID IID_ISimpleMath =
{ 0x7c8027ea, 0xa4ed, 0x467c, { 0xb1, 0x7e, 0x1b, 0x51, 0xce, 0x74, 0xaf, 0x57 } };//{CA3B37EA-E44A-49b8-9729-6E9222CAE84F}
static const GUID IID_IAdvancedMath =
{ 0xca3b37ea, 0xe44a, 0x49b8, { 0x97, 0x29, 0x6e, 0x92, 0x22, 0xca, 0xe8, 0x4f } };interface ISimpleMath : public IUnknown
{
public:
virtual int Add(int nOp1, int nOp2) = 0;
virtual int Subtract(int nOp1, int nOp2) = 0;
virtual int Multiply(int nOp1, int nOp2) = 0;
virtual int Divide(int nOp1, int nOp2) = 0;
};interface IAdvancedMath : public IUnknown
{
public:
virtual int Factorial(int nOp1) = 0;
virtual int Fabonacci(int nOp1) = 0;
};
#endif
接下来定义了两个接口,GUID(Globally Unique Identifier全局唯一标识符)它能保证时间及空间上的唯一。
ISmipleMath接口里定义了四个方法,而IAdvancedMath接口里定义了二个方法。这些方法都是虚函数,而整个 ISmipleMath 与 IAdvancedMath 抽象类就作为二进制的接口。2.2 math.h文件 #include "interface.h"class CMath : public ISimpleMath,
public IAdvancedMath
{
private:
ULONG m_cRef;private:
int calcFactorial(int nOp);
int calcFabonacci(int nOp);public:
//IUnknown Method
STDMETHOD(QueryInterface)(REFIID riid, void **ppv);
STDMETHOD_(ULONG, AddRef)();
STDMETHOD_(ULONG, Release)(); // ISimpleMath Method
int Add(int nOp1, int nOp2);
int Subtract(int nOp1, int nOp2);
int Multiply(int nOp1, int nOp2);
int Divide(int nOp1, int nOp2); // IAdvancedMath Method
int Factorial(int nOp);
int Fabonacci(int nOp);
};
此类为实现类,他实现了ISmipleMath和IAdvancedMath两个接口类(当然也可以只实现一个接口类)。
请注意:m_cRef 是用来对象计数用的。当 m_cRef 为0组件对象应该自动删除。2.3 math.cpp文件 #include "interface.h"
#include "math.h"STDMETHODIMP CMath::QueryInterface(REFIID riid, void **ppv)
{// 这里这是实现dynamic_cast的功能,但由于dynamic_cast与编译器相关。
if(riid == IID_ISimpleMath)
*ppv = static_cast(this);
else if(riid == IID_IAdvancedMath)
*ppv = static_cast(this);
else if(riid == IID_IUnknown)
*ppv = static_cast(this);
else {
*ppv = 0;
return E_NOINTERFACE;
} reinterpret_cast(*ppv)->AddRef(); //这里要这样是因为引用计数是针对组件的
return S_OK;
}STDMETHODIMP_(ULONG) CMath::AddRef()
{
return ++m_cRef;
}STDMETHODIMP_(ULONG) CMath::Release()
{
ULONG res = --m_cRef; // 使用临时变量把修改后的引用计数值缓存起来
if(res == 0) // 因为在对象已经销毁后再引用这个对象的数据将是非法的
delete this;
return res;
}int CMath::Add(int nOp1, int nOp2)
{
return nOp1+nOp2;
}int CMath::Subtract(int nOp1, int nOp2)
{
return nOp1 - nOp2;
}int CMath::Multiply(int nOp1, int nOp2)
{
return nOp1 * nOp2;
}int CMath::Divide(int nOp1, int nOp2)
{
return nOp1 / nOp2;
}int CMath::calcFactorial(int nOp)
{
if(nOp <= 1)
return 1; return nOp * calcFactorial(nOp - 1);
}int CMath::Factorial(int nOp)
{
return calcFactorial(nOp);
}int CMath::calcFabonacci(int nOp)
{
if(nOp <= 1)
return 1; return calcFabonacci(nOp - 1) + calcFabonacci(nOp - 2);
}int CMath::Fabonacci(int nOp)
{
return calcFabonacci(nOp);
}
CMath::CMath()
{
m_cRef=0;
}
此文件是CMath类定义文件。
#include <iostream>using namespace std;int main(int argc, char* argv[])
{
ISimpleMath *pSimpleMath = NULL;//声明接口指针
IAdvancedMath *pAdvMath = NULL; //创建对象实例,我们暂时这样创建对象实例,COM有创建对象实例的机制
CMath *pMath = new CMath; //查询对象实现的接口ISimpleMath
pMath->QueryInterface(IID_ISimpleMath, (void **)&pSimpleMath);
if(pSimpleMath)
cout << "10 + 4 = " << pSimpleMath->Add(10, 4) << endl; //查询对象实现的接口IAdvancedMath
pSimpleMath->QueryInterface(IID_IAdvancedMath, (void **)&pAdvMath);
if(pAdvMath)
cout << "10 Fabonacci is " << pAdvMath->Fabonacci(10) << endl; pAdvMath->Release();
pSimpleMath->Release();
return 0;
}
此文件相当于客户端的代码,首先创建一个CMath对象,再根据此对象去查询所需要的接口,如果正确得到所需接口指针,再调用接口的方法,最后再将接口的释放掉。