请教早绑定(early binding)的问题

ookaiii 2001-05-13 11:00:00

各位:本人在学习Automation时发现所看潘爱民的<<com原理与应用>>和msdn中关

于 早绑定(early binding)的说法有冲突,请给指出究竟谁的解答是正确的

early binding?还是我理解有错?谢谢!

<<com原理与应用>> p359:
"通过早绑定,像vb或vba这样的控制器可以预处理basic代码,在编译时刻

把属性和方法符号转换到分发id,然后再检查属性类型,方法的返回类型和方法

参数,必要时给出编译时刻错误信息。"


msdn :

Early Binding: VTBL Binding
A VTBL is a data structure containing the addresses (pointers) for the

methods and properties of each object in an Automation server. Using

the VTBL is generally known as early binding in VBA. Frequently, early

binding requires type information provided in the form of a type

library. This type information allows VBA to perform compile-time

syntax and type checking. At run time, this type of binding is faster,

as the entry points for the Automation server are already known and the

data types and syntax have already been verified.

ID binding :
The ability to bind member names to dispatch identifiers (DISPIDs) at

compile time (for example, by obtaining the IDs from a type library).

This approach eliminates the need for calls to

IDispatch::GetIDsOfNames, and results in improved performance over

late-bound calls. See also late binding and VTBL binding.

我的感觉:
好像潘爱民的解释是ID Binding,而不是Early Binding,但我不能说就

是理解了early binding,所以我希望大家给我一个准确的答案,最好附上理由,

多谢!
...全文
212 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
ookaiii 2001-05-16
  • 打赏
  • 举报
回复
潘老师答复:
谢谢你和网友们的热烈讨论。我又仔细查看了MSDN中关于early binding和late
binding的各种说法,结合我两年多以前的写作过程,答复如下:

msdn中关于late binding的说法都是一致的,但是关于early binding的说法并不一
致,通过比较之后,我认为下面的说法比较合理:

http://msdn.microsoft.com/library/devprods/vs6/vbasic/vbcon98/vbconhowbindin
gaffectsolecomponentperformance.htm

early binding包括两种形式:dispid binding和vtbl binding。对于VB的客户程序,
定义为“dim obj as Xxx[InterfaceName]”,如果是dual interface,则使用vtbl
binding,否则使用dispid binding。为了使用early binding,组件必须提供
typelib。

对于late binding,在VB客户代码中,定义为“dim obj as object”,不管对象是否
支持双接口,都要先调用IDispatch::GetIDsOfNames,再调用IDispatch::Invoke。

从效率来考察,很显然,vtbl binding > dispid binding > late binding。对于同一
进程内的automation对象,vtbl binding比dispid binding效率提高比较明显,而
dispid binding比late binding提高幅度并不明显;但是对于进程外的automation对
象,vtbl binding比dispid binding效率提高并不明显,但是dispid binding比late
binding提高幅度比较明显,因为late binding需要两个跨进程(甚至跨机器)调用,而
dispid binding和vtbl binding只需要一个跨进程调用。

我在写作“COM原理与应用”时,当时情况下dual interface还不是很普及,MFC也不支
持双接口。所以我只是介绍了双接口,没有过多介绍双接口的特性。其实dual
interface之所以称为双接口,原因就在于它既是IDispatch接口,也是一个普通的
IUnknown接口(可以通过vtbl访问属性和方法),所以vtbl binding是它的自然属性(但
当时我没有看到过这个叫法,或许是我孤陋寡闻)。所以,仅仅把vtbl binding当作
early binding与late binding对立起来,就好比把dual interface与IDispatch对立起
来,而根本体现不出在compile-time还是runtime绑定的意思。

现在随着dual interface的普及(MS提供的许多对象库都是用dual interface定义的),
把vtbl binding与dispid binding合起来称为early binding,我认为这也是合理的。
因为这两种binding都需要在compile-time完成,而且都需要类型库的支持,这才反映
出与late binding对立的实质。

——————————

另外的说法,如同你们在讨论中提到的,认为early binding只包括vtbl binding,从
而把early binding/dispid binding/late binding三者对立起来,这样的结果是,讨
论binding模式就需要考虑接口的类型。这种提法也能成立,但我认为从客户的binding
过程以及数据类型安全的角度来看,这种提法不很合理。

---------------------

前面提到了,所谓vtbl binding,其实就是使用dual interface的另一面。如果组件对
象的接口是dual interface,当我们在VB/VBA中写下 “dim myApp as new
Word.Application”时,VB就用到了vtbl binding。

如果我们要在VC程序中使用vtbl binding,首先给出双接口的定义,然后在程序中创建
对象,比如你的双接口为IYourDualInteface,它有一个方法Method1,那么你可以这样
用vtbl binding:

IYourDualInterface *pItf;
HRESULT hResult = pUnknown->QueryInterface(IID_IYourDualInteface, (void
**)&pItf);
if (SUCCEED(hResult)) {
pItf->Method(...);
...
}

假设方法的id为1,那么使用dispid binding的客户代码如下:

IYourDualInterface *pItf;
HRESULT hResult = pUnknown->QueryInterface(IID_IYourDualInteface, (void
**)&pItf);
if (SUCCEED(hResult)) {
// 参数准备
pItf->Invoke(1, ID_NULL, lcid, DISPATCH_METHOD, ...);
...
}

如果是late binding,它不需要知道有关接口IYourDualInteface的任何信息(包括IID
和类型信息),客户代码如下:

IDispatch *pItf;
HRESULT hResult = pUnknown->QueryInterface(IID_IDispatch, (void **)&pItf);
if (SUCCEED(hResult)) {
LPOLESTR methodName = L"Method1";
DISPID dispID;
hResult = pItf->GetIDsOfNames(ID_NULL, &methodName, 1, lcid, &dispID);
if (SUCCEED(hResult)) {
// 参数准备
pItf->Invoke(dispID, ID_NULL, lcid, DISPATCH_METHOD, ...);
...
}
...
}

------------------------------

希望以上的解释对你和大家有所帮助。

也为书中的不足向大家表示歉意。这本书有许多不完善的地方,请大家阅读时注意。

潘爱民

-----Original Message-----
发件人: Fei <ookaiii@sohu.com>
收件人: panaimin@263.net <panaimin@263.net>
日期: 2001年5月15日 18:26
主题: 有一问题请教


潘老师:

你好!我是你的一名忠实读者,学习《com原理与应用》之后很有收获,此著作更是市场
上难得的学习

com的好教材,我向您表示衷心感谢!
现有一问题请教,我曾在www.csdn.net上发过帖子,(见

http://www.csdn.net/expert/topic/120/120017.shtm,

http://www.csdn.net/expert/topic/120/120015.shtm。)和众人讨论之后未果,还望
您百忙之中给于解答,本

人不胜感激!

<<com原理与应用>>Automation一章发现与msdn中关于 早绑定(early binding)的说法
有冲突,请给

指出究竟谁的解答是early binding?

<<com原理与应用>> p359:
"...
通过早绑定,像vb或vba这样的控制器可以预处理basic代码,在编译时刻把属性
和方法符号转换到分发id

,然后再检查属性类型,方法的返回类型和方法参数,必要时给出编译时刻错误信息。
"

msdn :

Early Binding: VTBL Binding
A VTBL is a data structure containing the addresses (pointers) for the
methods and properties of

each object in an Automation server. Using the VTBL is generally known as
early binding in VBA.

Frequently, early binding requires type information provided in the form of
a type library. This

type information allows VBA to perform compile-time syntax and type
checking. At run time, this

type of binding is faster, as the entry points for the Automation server are
already known and

the data types and syntax have already been verified.

ID binding :

The ability to bind member names to dispatch identifiers (DISPIDs) at
compile time (for example,

by obtaining the IDs from a type library). This approach eliminates the need
for calls to

IDispatch::GetIDsOfNames, and results in improved performance over
late-bound calls. See also

late binding and VTBL binding.

我所认为的各种binding之间的关系:

假如接口 IX声明称dual的那么
1。可以通过IDispatch来访问IX中的成员
a. Early Binding(是ID Binding吗?)

b. Late Binding
2。通过VTBL访问(即VTBL Binding)
这么理解对么?


我的感觉:
好像<<com原理与应用>>中关于early binding的解释是msdn中的ID
Binding,early binding是ID

Binding么?是VTBL Binding?还是两者都是?VTBL Binding完成的是不是 从对象的方
法或属性到VTBL内容的

映射(好像介绍VTBL Binding的资料较少)?另外:我很想知道vtbl binding究竟在程序
上怎样实现?有范例么

?您能解释一下各种绑定之间的关系么?希望您给我一个答案,
您的答复我将在csdn上贴出,让与我有相同疑惑的网友得到解答(已经有人要求了),可
以么?本人静

听高论!

谢谢!

Fei
ookaiii@sohu.com




礼!

Fei
ookaiii@sohu.com

ookaiii 2001-05-16
  • 打赏
  • 举报
回复
昨天我给潘老师写信请教关于binding的问题,他很快给了答复,我觉得解释得很透彻,贴出来个大家看看,如果大家看过以后没有什么疑义,那两天我再给分,谢谢大家!
horris 2001-05-15
  • 打赏
  • 举报
回复
to ookaiii(ookaiii):你的想法基本上和我一样。
我现在倾向于认为,VTBL Binding/ID Binding都是Early Binding的一种,但是ID Binding是针对于IDispatch而言的。
对于VTBL,我想它是一个表,表中对应接口的每个方法都有一项,该项存放该方法的实现函数的地址,另外考虑到多继承的情况,这个表还要有一个指向类实例的指针(pThis)。客户端得到的接口指针就指向VTBL,要调用某个方法,就通过VTBL找到该方法函数的地址,并从VTBL取出pThis指针,用stdcall的调用约定(pThis作为隐含参数)调用方法函数。实际上在C++中调虚函数就是这么作的。所有可以作COM客户的开发工具都在内部实现这个过程,只不过对于VB这类的工具,语法上没有直接的途径可以访问VTBL。
vcmfc 2001-05-15
  • 打赏
  • 举报
回复
其实老潘说法的意思也是对的,前绑定主要是用在编译时,而后绑定是用在动态运行时,而且只有C++才有VTable,而对于Basic程序而言是没有什么VTable的.
vcmfc 2001-05-15
  • 打赏
  • 举报
回复
"所以这句话若改说成“VTBL Binding是针对非IDispatch接口的(包括dual)"

Dual接口包括了自定义接口,

应该改为:

“VTBL Binding是针对非IDispatch接口的"
ookaiii 2001-05-15
  • 打赏
  • 举报
回复
我已发信问潘老师了,也许很快能有答案
ookaiii 2001-05-15
  • 打赏
  • 举报
回复
感谢horris的回复,
我们关于ID Binding的理解都是一致的,其DISPID是在编译时便由编译器预处理了,

而后再使用时不再查找名字对应的ID(即不调用GetIDsOfNames),我觉得late Binding我们

也没有什么疑惑,他只是在临到使用对象的方法或属性时才调用GetIDsOfNames来查找相应

的DISPID(即运行时才绑定DISPID)。
但我认为你所说“VTBL Binding是针对非IDispatch接口的(包括dual),如果你的接

口是自定义接口,客户端只能使用VTBL绑定。”似有不妥,VTBL Binding是对立于别的

Binding的,因为从道理上说诸如ID Binding,Late Binding,并没有能力限制客户不能通过

VTBL来对对象进行操作,所以这句话若改说成“VTBL Binding是针对非IDispatch接口的(

包括dual),如果你的接口是自定义接口,假如对象又没有IDispatch接口,那么客户端只

能使用VTBL绑定。”我觉得更合理些

VTBL Binding是不是完成的是 从对象方法或属性到VTBL的映射?
另外:我很想知道vtbl binding究竟在程序上怎样实现?有范例么?

关于自动化:

我认为自动化给我们带来的是一个拥有属性方法的对象,如果我们站在较为底层的位

置上来看这个对象,它拥有一个IDispatch这个万能接口,通过这个接口,我们可以访问处

理由IDispatch所定义的方法和属性,如果在制作这个对象的时候把他的接口声明成dual的

,那么在其对应的type library中会描述其VTBL接口



我所认为的各种binding之间的关系:
假如接口 IX声明称dual的那么
1。可以通过IDispatch来访问IX中的成员
a. Early Binding(可能就是ID Binding(horris的提示可以解释的通为什么潘爱民和msdn上的说法))

b. Late Binding
2。通过VTBL访问(即VTBL Binding)

请继续关注,谢谢!
horris 2001-05-14
  • 打赏
  • 举报
回复
我认为,针对IDispatch及派生于IDispatch的dual接口,才有必要区分Early binding/Late binding。IDispatch接口的VTBL是已知的、固定的,客户端访问它可以使用迟绑定。ID binding就是指的是dual/IDispatch的Early Binding。它可以从方法/属性名预先知道DISPID,而不是在运行时通过GetIDsOfNames这种效率较低的方法获得。
VTBL Binding是针对非IDispatch接口的(包括dual),如果你的接口是自定义接口,客户端只能使用VTBL绑定。它需要接口的type library以知道接口的VTBL结构。对于dual接口,VTBL绑定比ID绑定效率要高,因为它直接通过VTBL调用方法而不是通过IDispatch::Invoke.
horris 2001-05-14
  • 打赏
  • 举报
回复
我认为,针对IDispatch及派生于IDispatch的dual接口,才有必要区分Early binding/Late binding。IDispatch接口的VTBL是已知的、固定的,客户端访问它可以使用迟绑定。ID binding就是指的是dual/IDispatch的Early Binding。它可以从方法/属性名预先知道DISPID,而不是在运行时通过GetIDsOfNames这种效率较低的方法获得。
VTBL Binding是针对非IDispatch接口的(包括dual),如果你的接口是自定义接口,客户端只能使用预绑定。它需要接口的type library以知道接口的VTBL结构。对于dual接口,VTBL绑定比ID绑定效率要高,因为它直接通过VTBL调用方法而不是通过IDispatch::Invoke.
ookaiii 2001-05-14
  • 打赏
  • 举报
回复
大家帮忙看看那,谢谢,

16,547

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧