首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网络技术 > 网络基础 >

用基准C编写COM(八)COM in plain C,Part8

2014-04-18 
用标准C编写COM(八)COM in plain C,Part8原文:http://www.codeproject.com/Articles/17038/COM-in-plain-C

用标准C编写COM(八)COM in plain C,Part8

原文:http://www.codeproject.com/Articles/17038/COM-in-plain-C-part-8

下载例程-419Kb

内容

简介脚本代码持久化脚本代码和“命名项”调用脚本中的特定函数查询/设置脚本中变量的值查询/设置脚本中变量的值


简介

在前面的章节中,我们学会了如何创建Activex脚本宿主。虽然这些章节覆盖了编写一个脚本宿主的的大部分方面,但是,这里还有其它一些 你的脚本宿主也许想要使用的 更esoteric(深奥,机密)的特性。本章节将会详细的介绍其中一些机密特性。


脚本代码持久化


在先前的脚本宿主示例中,我们用runScript函数打开脚本引擎,运行脚本,然后关闭引擎。这个函数中,脚本引擎被加载/分析,执行,然后释放(执行完成之后)。


但是,也许有时候,你希望添加一些脚本到引擎,并且让它们一直驻留在里面,即使这些脚本没有被执行。可能,你希望这些脚本能够被任何 能够被相同引擎的IActiveScript识别的 其它脚本所调用。事实上,或许你还想把这些脚本作为"ram-based macros"集合。ActiveX脚本引擎让这成为可能。但我们还需要从以下两方面改变我们的方法:

    当我们把脚本作为“宏”添加的时候,我们需要为ParseScriptText函数指定SCRIPTTEXT_ISPERSISTENT标志。这告诉引擎保留内部已分析\加载过的脚本,即使在ParseScriptText返回之后。

    我们不能在所有宏被使用之前释放引擎的IActiveScript对象。如果这样做,那些宏最终会被卸载掉。

最好的做法是 在引擎处于INITIALIZED状态时 添加这些宏,但要在引擎被设置为STARTED或CONNECTED状态之前。ParseScriptText不会尝试运行这些脚本,而是对其语法分析,并在ParseScriptText返回的时候,在内部把这些脚本保存起来。这些脚本会驻留在引擎中,直到我们释放了引擎的IActiveScript对象,即使在这中间,我们调用了其它脚本或者方法。


ScriptHost7目录中,你会找到一个说明这一点的例子。我们添加一个VB脚本给引擎,并指定 SCRIPTTEXT_ISPERSISTENT 标志。为了简单,这个VB脚本被作为全局变量,像下面这样嵌入在我们的EXE中:

STDMETHODIMP GetItemInfo(MyRealIActiveScriptSite *this, LPCOLESTR   objectName, DWORD dwReturnMask, IUnknown **objPtr, ITypeInfo **typeInfo){   HRESULT    hr;   hr = E_FAIL;   if (dwReturnMask & SCRIPTINFO_ITYPEINFO) *typeInfo = 0;   if (dwReturnMask & SCRIPTINFO_IUNKNOWN)   {      *objPtr = 0;      // If the engine is asking for our "VB" named item we created,      // then we know this is the JScript engine calling. We need to      // return the IDispatch for VBScript's "global named item".      if (!lstrcmpW(objectName, L"VB"))      {         hr = VBActiveScript->lpVtbl->GetScriptDispatch(VBActiveScript,            0, objPtr);      }   }   return(hr);}

ScriptHost10中,是jscript调用vbscript的例子。

顺便提一句,你也许对SCRIPTITEM_GLOBALMEMBERS标志有点奇怪。先回想一下我们前面处理一个命名项时,脚本必须像一个对象名那样引用项的名字,例如:

VB.SayHello()

当用SCRIPTITEM_GLOBALMEMBERS标志创建项时,指出了对象名是可选的。例如,上面的代码可以工作,或者还可以这样用:

SayHello()

所以我们做的只是让jscript 在调用vb脚本的SayHello函数时 就像在调用另一个 本地(local) jscript函数。换言之,它或多或少是一种 隐藏命名项麻烦细节的 理论意义上的 捷径。

但这个好处是要付出代价的。就像全局项那样,这些使用SCRIPTITEM_GLOBALMEMBERS标记的项之间可能会出现名字冲突。 

热点排行