为了跟随技术的潮流,我在一个windows application项目中放弃了 mfc,转入 c++.net winform. 虽然winform 运行速度无法与 mfc 相提并论,但设计效率大大提高,特别是有了自定义 control, 代码量强度大大降低, 而且很多底层代码 (unmanaged) 可以直接移植使用。当我进一步跳到 c# 是, 底层代码就有了问题,c# 没有 unmanaged code 一说。解决方案有两个: 1)在 c# 中声明 api , 这是流行的方法, 2)生成 .net dll 供c# 直接使用, 当dll 被加入c# reference 后,能立即看到各接口及属性。
使用方法 1 有时很烦琐,例如通过 TAPI 使用modem, 或使用 TCPIP. 第二种方法对不懂 c++ 的人来说是一种考验。 在 vs 2005 中产生一个c++.net 的dll project, 然后用 __gc class 重新封装。
_CConnection 与 CConnection 分别是unmanged 与 managed code 的基类
#define EXT(func) /
if (! m_bEnableException) /
return func; /
else if ((func)) /
return true; /
else /
throw new Exception();
public __gc class CConnection
{
protected:
_CConnection* m_pConnection; //unmanaged class
bool m_bEnableException;
public:
__property bool get_EnableException() { return m_bEnableException; }
__property void set_EnableException(bool bEnableException) { m_bEnableException = bEnableException; }
virtual bool IsConnected() { return m_pConnection->IsConnected(); }
virtual bool Read(unsigned char buffer __gc[], int length)
{
unsigned char __pin *pBuffer = &buffer[0];
EXT(m_pConnection->Read((char*) pBuffer, length));
}
virtual bool Read(unsigned char buffer __gc[], int offset, int length)
{
unsigned char __pin *pBuffer = &buffer[offset];
EXT(m_pConnection->Read((char*) pBuffer, length));
}
virtual bool Write(unsigned char buffer __gc[], int length)
{
unsigned char __pin *pBuffer = &buffer[0];
EXT(m_pConnection->Write((char*) pBuffer, length));
}
...
public __gc class CProtocol
{
protected:
_CProtocol* m_pProtocol;
CConnection* m_pConnection;
bool m_bEnableException;
bool m_bLastCommResult;
bool m_bChecErrorEnabled;
public:
__event EventHandler* OnCommunicationTimeoutStatusChanged;
protected:
bool CheckTimeout(bool bCommResult)
{
if (! m_bChecErrorEnabled) return bCommResult;
bool b = !(!bCommResult && IsTimeout());
if (m_bLastCommResult != b) {
m_bLastCommResult = b;
if (OnCommunicationTimeoutStatusChanged != NULL) {
OnCommunicationTimeoutStatusChanged->Invoke(__box(b), NULL);
}
}
return bCommResult;
}
public:
__property bool get_EnableException() { return m_bEnableException; }
__property void set_EnableException(bool bEnableException) { m_bEnableException = bEnableException; }