COM 组件设计与应用(六)——用 ATL 写第一个组件(vc.net)
2006-07-22 22:56:14 来源:WEB开发网五、实现接口函数
鼠标双点图八中CFun\基项和接口\Add(...)就可以开始输入函数实现了:
STDMETHODIMP CFun::Add(long n1, long n2, long *pVal)
{
*pVal = n1 + n2;
return S_OK;
}
这个太简单了,不再浪费“口条”。下面我们实现字符串连接的Cat()函数:STDMETHODIMP CFun::Cat(BSTR s1, BSTR s2, BSTR *pVal)
{
int nLen1 = ::SysStringLen( s1 ); // s1 的字符长度
int nLen2 = ::SysStringLen( s2 ); // s2 的字符长度
*pVal = ::SysAllocStringLen( s1, nLen1 + nLen2 );// 构造新的 BSTR 同时把 s1 先保存进去
if( nLen2 )
{
::memcpy( *pVal + nLen1, s2, nLen2 * sizeof(WCHAR) ); // 然后把 s2 再连接进去
// wcscat( *pVal, s2 );
}
return S_OK;
}
学生:上面的函数实现,完全是调用基本的 API 方式完成的。老师:是的,说实话,的确比较烦琐。
学生:我们是用memcpy()完成连接第二个字符串功能的,那么为什么不用函数 wcscat()那?
老师:多数情况下可以,但你需要知道:由于BSTR包含有字符串长度,因此实际的BSTR字符串内容中是可以存储L''\0''的,而函数 wcscat() 是以L''\0''作为复制结束标志,因此可能会丢失数据。明白了吗?
学生:明白,明白。我看过《COM 组件设计与应用(三)之数据类型》后就明白了。那么老师,有没有简单一些的方法那?
老师:有呀,你看......STDMETHODIMP CFun::Cat(BSTR s1, BSTR s2, BSTR *pVal)
学生:哈哈,好!使用了 CComBSTR,这个就简单多了。CComBSTR::Copy()和CComBSTR::Detach()有什么区别?
{
CComBSTR sResult( s1 );
sResult.AppendBSTR( s2 );
*pVal = sResult.Copy();
// *pVal = sResult.Detach();
return S_OK;
}
老师:CComBSTR::Copy() 会制造一个 BSTR 的副本,另外CComBSTR::CopyTo()也有类似功能。而CComBSTR::Detach()是使对象与内部的 BSTR 指针剥离,这个函数由于没有复制过程,因此速度稍微快一点点。但要注意,一但剥离后,就不能再使用该对象啦。
学生:老师,您讲的太牛啦,我对您的敬仰如巍巍泰山,直入云霄......
老师:STOP,STOP!留作业啦......
1、自己先按照今天讲的内容写出这个组件;
2、不管你懂不懂,一定要去观察 IDL 文件,CPP 文件;
3、编译后,看都产生了些什么文件?如果是文本的文件,就打开看看;
4、下载本文的示例程序(vc.net 2003版本)编译运行,看看效果。然后预习一下示例程序中的调用方法;
学生:知道啦,快下课吧,我要上厕所,我都憋的不行了......
老师:下课!别忘了顶我的帖子呀......
六、小结
本回介绍第一个ATL组件程序的建立步骤,而如何使用该组件,敬请关注《COM 组件设计与应用(七)》。
注1:Apartment,系统通过隐藏的窗口消息来排队组件调用,因此我们可以暂时不考虑同步问题。注意,是暂时哈。
注2:双接口表示在一个接口中,同时支持自定义接口和 IDispatch 接口。以后,以后,以后就讲。因为双接口非常重要,我们以后会天天讲、夜夜讲、常常讲------简称“三讲”:)
注3:组件的重用方法有2个,聚合和包容。
注4:这些都是 IDL 文件中的概念,以后用到什么,就介绍什么。
更多精彩
赞助商链接