话说回来,vb易用的一个主要领域是,对COM组件的调用。用vb调用COM组件的属性和方法,就像调用本地的一样,代码书写很自然。因为vb不仅支持一般的接口方法调用,还支持通过IDispatch接口进行自动化调用。
vc++针对COM组件编程,提供了两组类库:(_com_ptr_t,_variant_t,_bstr_t)和(CComPtr,CComVariant,CComBSTR),使用起来也很方便。但对IDispatch接口没有提供直接的支持,进行调用就非常繁琐了。
IDispatch接口是自动化领域最重要的接口。IDispatchEx接口是对IDispatch接口的扩展,是javascript等动态语言内部实现的基础。如果我们要在VC++中访问javascript中的对象,如果我们要进而对AJAX库进行二进制封装,就必须有一个简单易用的辅助类库作支撑。当然,如果要给PIMShell开发plugin,vb般的VC++开发也是最常用的编程范式。
总之,一个编程语言既要强大、灵活,又要简单易用,不仅需要编译器本身的支持,还需要辅助库的支持。接下来的文章,我们就通过一系列的设计,来实现vb般的vc++开发。
例如:网页中的javascript有一个函数Test,我们通过调用Test来对比不同语言不同范式的区别。(Test可通过window对象访问,具体细节我们以后再讨论。)
javascript
function Test(sMessage)
{
alert(sMessage);
}
//执行
window.Test("Hello World!");
vb(不是vbscript)
dim oMethod as Object
Set oMethod=window.Test
oMethod("Hello World!")
vb般的vc++
IDispatchPtr pMethod=CVB::get(window,L"Test"); CVB::Invoke1(pMethod,NULL,L"Hellow World!");
一般的vc++,(代码已简化,未检测必要的异常)
//get DISPID of "Test"
DISPID dispID;
LPCTSTR szName=L"Test";
window->GetIDsOfNames( IID_NULL, &ptName, 1, LOCALE_USER_DEFAULT, &dispID);
//get property of "Test"
_variant_t vResult;
DISPPARAMS dp = { NULL, NULL, 0, 0 };
window->Invoke( dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &dp, &vResult, NULL, NULL);
//ready
IDispatchPtr pMethod=vResult;
//invoke "Test"
_variant_t vParam=L"Hello World!";
dp.cArgs=1;
dp.rgvarg=&vParam;
pMethod->Invoke( NULL, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &dp, NULL, NULL, NULL);

本文探讨了VB与VC++在COM组件调用方面的差异,重点介绍了VC++如何通过IDispatch接口调用COM组件,并提出了简化调用过程的方法。
1156

被折叠的 条评论
为什么被折叠?



