COM试验VC版文档格式.docx
《COM试验VC版文档格式.docx》由会员分享,可在线阅读,更多相关《COM试验VC版文档格式.docx(14页珍藏版)》请在冰点文库上搜索。
![COM试验VC版文档格式.docx](https://file1.bingdoc.com/fileroot1/2023-5/1/7fb732c2-89ab-4277-9846-4fa1f7d81743/7fb732c2-89ab-4277-9846-4fa1f7d817431.gif)
⑵注销操作:
RegSvr32/uc:
\XXXXX.dll
⑶注册操作:
RegSvr32c:
⑷在运行客户程序前,必须先注册组件程序。
5.写出上机实验报告。
实验报告格式
1.画出实验所设计的COM组件的结构
2.关键代码
(1)组件部分的关键代码
①idl文件内COM对象和接口的关键定义代码
②C++文件中成员函数的关键实现代码
(2)客户端测试程序中组件调用部分的关键代码
3.实验结果
COM试验参考
一、建立ATL工程(注意:
和试验任务书要求的组件结构不同)
IMath
Add(longn1,longn2,long*pnVal)
Cat(BSTRs1,BSTRs2,BSTR*psVal)
步骤1:
建立一个工作区(WorkSpace)。
步骤2:
在工作区中,新建一个ATL工程(Project)。
命名为SimpleCom(如图1),并选择DLL方式(如图2)。
图1新建ATL工程
图2选择DLL类型
说明:
⑴DynamicLinkLibrary(DLL)表示建立一个DLL的组件程序。
⑵Executable(EXE)表示建立一个EXE的组件程序。
⑶Service(EXE)表示建立一个服务程序,系统启动后就会加载并执行的程序。
⑷Allowmergingofproxy/stubcode选择该项表示把“代理/存根”代码合并到组件程序中,否则需要单独编译,单独注册代理存根程序。
⑸SupportMFC支持MFC
⑹SupportMTS支持事务处理,即是否支持COM+功能。
二、增加ATL对象类
步骤3:
选择菜单Insert\NewATLObject\Object分类\SimpleObject项目。
见图3。
图3选择建立简单COM对象
⑴CategoryObject普通组件。
其中可以选择的组件对象类型很多,但本质上,就是让向导帮忙加上一些默认接口。
⑵CategoryControlsActiveX控件。
其中可以选择的ActiveX类型也很多。
⑶CategoryMiscellaneous辅助杂类组件。
⑷CategroyDataAccess数据库类组件。
步骤4:
增加自定义类CMath(接口IMath),见图4。
图4输入类中的各项名称
步骤5:
填写接口属性,见图5。
图5接口属性
⑴ThreadingModel选择组件支持的线程模型。
⑵Interface接口基本类型。
Dual表示支持双接口;
Custom表示自定义借口。
⑶Aggregation是否允许被别人聚合使用。
No表示不聚合。
⑷SupportISupportErrorInfo是否支持丰富信息的错误处理接口。
⑸SupportConnectionPoints是否支持连接点接口(事件、回调)。
⑹FreeThreadedMarshaler
三、添加接口成员函数
图6调出增加接口方法的菜单
图7增加接口函数Add
[in]表示参数方向是输入;
[out]表示参数方向是输出;
[out,retval]表示参数方向是输出,同时可以作为函数运算结果的返回值。
一个函数中,可以有多个[in]、[out],但[retval]只能有一个,并且要和[out]组合后在最后一个位置。
图8接口函数
实现代码如下:
STDMETHODIMPCMath:
:
{
//TODO:
Addyourimplementationcodehere
*pnVal=n1+n2;
returnS_OK;
}
四、添加第二个接口IStr。
完成上述步骤后,打开IDL文件(双击IMath接口),手工添加代码,其中UUID每个组件,每个接口都会不同。
//引入IUnknown和ATL已经定义的其它接口描述文件。
import"
oaidl.idl"
;
ocidl.idl"
//接口的完整描述
[
object,//表示本块描述的是一个接口
uuid(E34275D2-B3CA-4BCA-9AC7-0713ABE2F876),
helpstring("
IMathInterface"
),//说明文字
pointer_default(unique)//定义接口函数中参数所使用指针的默认属性
]
interfaceIMath:
IUnknown//接口叫IMathe派生自IUnknown
{//接口函数列表
[helpstring("
methodAdd"
)]HRESULTAdd([in]longn1,[in]longn2,[out,retval]long*pnVal);
};
//增加接口代码
[
object,
uuid(36A75A3F-94DE-47fe-AF51-0C0C65316A03),//手工产生的IID
IStrInterface"
),
pointer_default(unique)
]
interfaceIStr:
IUnknown//新建接口
{
//目前还没有任何接口函数
//增加接口代码结束
//类型库的完整描述
uuid(FBF0BE44-9E98-4189-809B-BEC4B67866CC),
version(1.0),
helpstring("
SimpleCom1.0TypeLibrary"
)
librarySIMPLECOMLib//#import时候的默认命名空间
importlib("
stdole32.tlb"
);
stdole2.tlb"
uuid(9D4F4C3B-A41F-4A3A-9FF2-F8784DBE2CC5),//组件的CLSID
MathClass"
coclassMath
//接口列表
[default]interfaceIMath;
//[default]表示接口IMath提供了IUnknown接口
interfaceIStr;
//在接口列表中添加新接口
};
其中手工产生GUID可借助于"
vc目录\Common\Tools\GuidGen.exe"
程序。
五、打开头文件(Math.h),手工增加类的派生关系和接口入口表,然后保存。
#ifndef__MATH_H_
#define__MATH_H_
#include"
resource.h"
//mainsymbols
/////////////////////////////////////////////////////////////////////////////
//CMath
classATL_NO_VTABLECMath:
publicCComObjectRootEx<
CComSingleThreadModel>
publicCComCoClass<
CMath,&
CLSID_Math>
publicIMath,//增加一个分隔符——逗号
publicIStr//增加一个基类
public:
CMath()
}
DECLARE_REGISTRY_RESOURCEID(IDR_MATH)
DECLARE_NOT_AGGREGATABLE(CMath)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CMath)
COM_INTERFACE_ENTRY(IMath)
COM_INTERFACE_ENTRY(IStr)//增加新接口到接口入口表
END_COM_MAP()
//IMath
STDMETHOD(Add)(/*[in]*/longn1,/*[in]*/longn2,/*[out,retval]*/long*pnVal);
#endif//__MATH_H_
六、为IStr接口增加一个字符串连接功能的函数。
图9添加接口函数Cat
CComBSTRsResult(s1);
sResult.AppendBSTR(s2);
*psVal=sResult.Copy();
七、编译DLL
按下F7键,编译器工作片刻后就会在注册表中注册你的新DLL了,这样一来其它的程序就可以使用它了。
图9编译dll
八、在VisualC++中新建工程,编写客户端程序,进行组件测试。
新建工程。
选择“Win32ConsoleApplication”,起名为“TestCom”,在下一个窗口中单击OK按钮接受所有默认值,最后单击Finish按钮。
新建文件
新建“C++SourceFile”文件并命名为“TestCom.cpp”,单击OK接受。
在空白文件中添加一些代码来测试COM服务器。
代码如下:
..\SimpleCom\SimpleCom.h"
//指明工程路径,引用头文件
..\SimpleCom\SimpleCom_i.c"
//各GUID在xxx_i.c文件中
#include<
iostream.h>
//输入输出
comutil.h>
//字符串类型转换
comdef.h>
voidmain(void)
HRESULThr;
IUnknown*pUnknown;
IMath*IMathAdd=NULL;
IStr*IStrCat=NULL;
GUIDMathCLSID;
hr=CoInitialize(0);
//COM库初始化
if(hr==S_OK){
hr=:
CLSIDFromProgID(L"
SimpleCom.Math.1"
&
MathCLSID);
hr=CoCreateInstance(MathCLSID,NULL,CLSCTX_INPROC_SERVER,IID_IUnknown,(void**)&
pUnknown);
if(hr==S_OK){
hr=pUnknown->
QueryInterface(IID_IMath,(void**)&
IMathAdd);
if(hr==S_OK){
longReturnValue;
IMathAdd->
Add(5,7,&
ReturnValue);
cout<
<
"
Theanswerfor5+7is:
ReturnValue<
endl;
Release();
}
QueryInterface(IID_IStr,(void**)&
IStrCat);
BSTRCatString=NULL;
IStrCat->
Cat(SysAllocString(L"
MiddleWare"
),SysAllocString(L"
Technology"
),&
CatString);
MiddleWare+Technology:
_bstr_t(CatString)<
IStrCat->
SysFreeString(CatString);
else{
cout<
CoCreateInstanceFailed."
<
CoUninitialize();
第3步:
编译并运行程序
按下F5键来编译程序,然后按下Ctrl+F5运行。
图13运行结果