一、前言
咱们用 atl 写了一个简单的 com 组件,之所以说简单,是因为在组件中,只实现了一个自定义(custom)的接口 ifun。当然如果想偷懒的话,我们可以把 200 个函数都加到这一个接口中, 果真如此的话,恐怕就没有人喜欢使用我们这个组件了。 一个组件既然可以提供多个接口,那么我们在设计的时候,就应该按照函数的功能进行分类,把不同功能分类的函数用多个接口表现出来。这样可以有如下的一些好处:
二、接口结构
1 import "oaidl.idl";
2 import "ocidl.idl";
3 [
4 object,
5 uuid(072ea6ca-7d08-4e7e-b2b7-b2fb0b875595),
6 helpstring("imathe interface"),
7 pointer_default(unique)
8 ]
9 interface imathe : iunknown
10 {
11 [helpstring("method add")] hresult add([in] long n1, [in] long n2, [out,retval] long *pnval);
12 };
13 [
14 uuid(cd7672f7-c0b4-4090-a2f8-234c0062f42c),
15 version(1.0),
16 helpstring("simple3 1.0 type library")
17 ]
18 library simple3lib
19 {
20 importlib("stdole32.tlb");
21 importlib("stdole2.tlb");
22 [
23 uuid(c6f241e2-43f6-4449-a024-b7340553221e),
24 helpstring("mathe class")
25 ]
26 coclass mathe
27 {
28 [default] interface imathe;
29 };
30 }; | 1-2 | 引入 iunknown 和atl已经定义的其它接口描述文件。import 类似与 c 语言中的 #include |
| 3-12 | 一个接口的完整描述 |
| 4 | object 表示本块描述的是一个接口。idl文件是借用了prc远程数据交换格式的说明方法 |
| 5 | uuid(......) 接口的 iid,这个值是 atl 自动生成的,可以手工修改或用 guidgen.exe 产生(注3) |
| 6 | 在某些软件或工具中,能看到这个提示 |
| 7 | 定义接口函数中参数所使用指针的默认属性(注4) |
| 9 | 接口叫 imathe 派生自 iunknown,于是 imathe 接口的头三个函数一定就是queryinterface,addref和release |
| 10-12 | 接口函数列表 |
| 13-30 | 类型库的完整描述(类型库的概念以后再说),下面所说明的行,是需要先了解的 |
| 18 | #import 时候的默认命名空间 |
| 23 | 组件的 clsid,cocreateinstance()的第一个参数就是它 |
| 27-29 | 接口列表 |
| 28 | [default]表示谁提供了iunknown接口 |
import "oaidl.idl";
import "ocidl.idl";
[
object,
uuid(072ea6ca-7d08-4e7e-b2b7-b2fb0b875595),
helpstring("imathe interface"),
pointer_default(unique)
]
interface imathe : iunknown
{
[helpstring("method add")] hresult add([in] long n1, [in] long n2, [out,retval] long *pnval);
};
[ // 所谓手工输入,其实也是有技巧的:把上面的接口描述(imathe)复制、粘贴下来,然后再改更方便哈
object, uuid(072ea6cb-7d08-4e7e-b2b7-b2fb0b875595),
// 手工或用工具产生的 iid
helpstring("istr interface"),
pointer_default(unique)
]
interface istr : iunknown
{
// 目前还没有任何接口函数 }; [ uuid(cd7672f7-c0b4-4090-a2f8-234c0062f42c), version(1.0), helpstring("simple3 1.0 type library")
]
library simple3lib
{
importlib("stdole32.tlb"); importlib("stdole2.tlb");
[
uuid(c6f241e2-43f6-4449-a024-b7340553221e),
helpstring("mathe class")
]
coclass mathe
{
[default] interface imathe;
interface istr; // 别忘了呦,这里还有一个那
};
}; class atl_no_vtable cmathe :
public ccomobjectrootex <ccomsinglethreadmodel>,
public ccomcoclass <cmathe, &clsid_mathe>,
public imathe, // 别忘了,这里加一个逗号
public istr // 增加一个基类
{
public:
cmathe()
{
}
declare_registry_resourceid(idr_mathe)
declare_protect_final_construct()
begin_com_map(cmathe) // 接口入口表。这里填写的接口,才能被queryinterface()找到
com_interface_entry(imathe)
com_interface_entry(istr)
end_com_map()import "oaidl.idl";
import "ocidl.idl";
[
object,
uuid(072ea6ca-7d08-4e7e-b2b7-b2fb0b875595),
helpstring("imathe interface"),
pointer_default(unique)
]
interface imathe : iunknown
{
[helpstring("method add")] hresult add([in] long n1, [in] long n2, [out,retval] long *pnval);
};
[ object,
uuid(072ea6cb-7d08-4e7e-b2b7-b2fb0b875595),
helpstring("istr interface"),
pointer_default(unique)
]
interface istr : iunknown
{
[helpstring("method cat")] hresult cat([in] bstr s1, [in] bstr s2, [out,retval] bstr *psval);
};
[
object,
uuid(072ea6cc-7d08-4e7e-b2b7-b2fb0b875595),
helpstring("imathe2 interface"),
pointer_default(unique)
]
interface imathe2 : iunknown
{ // 下面这个add()函数,只有idl中的声明,而不用增加任何程序代码,因为这个函数早在 imathe 中就已经实现了
[helpstring("method add")] hresult add([in] long n1, [in] long n2, [out,retval] long *pnval);
};
[
uuid(cd7672f7-c0b4-4090-a2f8-234c0062f42c),
version(1.0),
helpstring("simple3 1.0 type library")
]
library simple3lib { importlib("stdole32.tlb"); importlib("stdole2.tlb"); [ uuid(c6f241e2-43f6-4449-a024-b7340553221e),
helpstring("mathe class")
]
coclass mathe
{
[default] interface imathe;
interface istr;
interface imathe2; // 别忘了,这里还有一行呢!
};
};
4-2、打开头文件,增加派生关系和接口入口表class atl_no_vtable cmathe :
public ccomobjectrootex <ccomsinglethreadmodel>,
public ccomcoclass <cmathe, &clsid_mathe>,
public imathe,
public istr, // 这里增加一个逗号
public imathe2 {
public:
cmathe()
{
}
declare_registry_resourceid(idr_mathe)
declare_protect_final_construct() begin_com_map(cmathe)
com_interface_entry(imathe)
com_interface_entry(istr)
com_interface_entry(imathe2)
end_com_map() hresult mul([in] long n1, [in] long n2, [out,retval] long *pnval); Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器