分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.youkuaiyun.com/jiangjunshow
也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!
Question:
什么是IDL和MIDL?
Answer:
IDL是接口定义语言。
MIDL是Microsoft的IDL编译器。
在用IDL对接口和组件进行了描述后,可以用MIDL进行编译,生成相应的代理和存根DLL的C代码。
一个例子:
import “unknown.idl” ///用于将其他IDL文件中的定义包含到当前文件中
///Interface IX
[ ///注意是[ ]不是 {}
object, ///所定义的接口是一个COM接口
uuid(32bb8323-b41b-11cf-a6bb-0080c7b2d682), ///相应的接口IID
helpstring(“IX Interface”), ///将帮助串放入类型库
pointer_default(unique) ///这类指针可以为空,函数内可以修改它们的值,但不能指定别名
]
interface IX:IUnknown
{
///in关键字告诉MIDL需要将此参数值从客户传递给组件,存根代码不需要送回任何值。
HRESULT FxStringIn([in,string]wchar_t* szIn);
///out关键字告诉MIDL参数仅被用来从组件向客户传回有关的数据,
///代理不需要对输出参数进行列集,也不需要将参数传给组件。
HRESULT FxStringOut([out,string]wchar_t* szout);
///COM对字符串的标准约定是Unicode字符(即wchar_t)
}
IDL文件可以定义C和C++风格的结构,并可用它们作为函数的参数。
当IDL文件中有一个library时,MIDL将生成一个类型库。
MIDL为接口生成相应的代理和存根的C代码。
为得到一个代理/存根DLL,需要编译和链接MIDL生成的C文件。
宏REGISTER_PROXY_DLL将完成代理/存根DLL在注册表中的注册操作。
有了IDL和MIDL我们就可以象调用进程内组件那样进行跨进程边界的函数调用,并对参数进行列集(marshal)。
Question:
什么是代理和存根DLL?
Answer:
客户与一个模仿组件的DLL进行通信,这个DLL可以完成参数的列集,此组件被称为代理。
一个代理就是同另一个组件行为相同的组件。
代理必须是DLL形式。
组件还需要一个存根的DLL,以便对从客户传来的数据进行散集。
存根也将对传回给客户的数据进行列集。
接口定义语言(IDL)简介
1.ATL不为实现类创建虚函数表,因此初始化成员放在一个公共的函数中(啥意思?!).
2.IDL(接口定义语言)
3.IDL文件由MIDL编译器编译。
4.IDL基础:
接口定义语言是一种方法,通过这种方法,可以定义COM对象所支持的接口。一个COM对象的IDL文件主要包括两个
主要的元素:接口声明和类型库声明。
5.接口
接口是COM组件的一个关键部分,由关键字interface定义。接口的属性包括:
object, uuid(), helpstring(), pointer_default()。
<1>object
object属性是指定接口是COM接口的方法。没有object属性,接口被认为是DCE RPC(分布式计算环境远程过程调用)微软因此增加了object属性,作为为了支持COM。所有你定义的COM接口将有object标志。即所有的COM接口必须要有object属性。
<2>uuid
这指定了接口的GUID,使接口被唯一的标示。
<3>helpstring
最大长度255字节
<4>pointer_default
服务器程序可以在不同的地址空间或不同的机器上运行。这防止客户端程序直接访问服务器程序的内存,反之亦然。因此,当传递指针参数时,指针的地址需要被转换到服务器程序的地址空间中去。pointer_default属性表明这种转换如何发生,对于指针什么样的值是允许的。当指定参数为一个指针是,几个含糊不清的地方需要解决,以确定指针该如何处理。pointer_default()属性指定了默认怎样处理在接口中所有方法的参数。因此除非在参数中显式的指定,pointer_default()值将被应用于这个接口所有方法和属性中所有的指针参数。pointer_default()可能的值为ref,unique,ptr。默认为unique。ref(引用)属性指定NULL不是一个有效的指针和指针必须是一个有效的值。而且指针值是一个常量;指针必须不能改变成内存中的另一个位置,最后你不能改变指针引用的那块分配内存结构的大小。unique允许空指针,并且它可以从空转到非空,反之依然。这样由于可能为空,就不能用于指定结构的大小,如数组。ptr属性页被作为完全指针引用(full pointer),这是闲置最小的指针选项。
<5>接口声明:(类似于C++)
指令_declspec(uuid(x)),这条指令将使接口被打上GUID的烙印,所以,后来如果你指定_uuidof(interface),与接口相关联的GUID将自动被返回。这样很容易访问GUID,例如声明_declspec(uuid())struct _declspec(uuid("C552B896-F10C-480A-871D-0FD926D1C872" http://www.blogcn.com/images/wink.gif)
Istopwatch : public IUnknown
{
...
}
以后无论那里使用uuidof(IStopwatch)即可,例如
hr = CoCreate