C++有时候会需要调用JS代码,这对于C++来说或者对于国内来说一直是比较蛋疼的问题,主要是资料少,微软提供了一个COM组件,里面包含有JS引擎,这个组件就是:msscript.dll。
此文件在C:\Windows\SysWOW64目录下,这个COM组件里不止有JS引擎还有VB的引擎,也就是可以传入VB的代码获得返回值。但简中网络上此组件的资料少之又少,鄙人也是拿来主义,用老前辈提供的一个操作msscript.dll的类来调用JS,特此写下这篇帖子记录使用过程,以免忘记,为以后再次使用提供说明。
首先导入前辈提供的一个MSJsMgr.h文件和MSJsMgr.cpp文件,此操作类提供了若干函数,测试后发现就下面这个能用:
runScriptString(generd, urant);//执行字符串格式的 JS 脚本
此操作类提供了从JS文件加载JS脚本的方法,估计是输入目标文件地址的处理有问题,也搞不清是哪里有问题,目前只有上面那个函数能用,鄙人的办法就是把JS脚本存在一个txt文件里,然后用API读出文件里的文本,在用上面的函数调用,效果也是差不多的。
但是要注意txt文件里的JS脚本不能有换行,需要把JS脚本里的换行全部删除后才能成功调用;至于怎么向JS脚本里的函数输入参数,这里可以用CString类型里的字符串处理方法来插入字符串。
下面是一个例子:
(function(){return ;})();
目标是在return 后插入2+3,这样JS脚本执行后会返回5。
把上面这段脚本存入一个txt文件里:ChunGe.txt
CMSJsMgr mport;
CString estion, generd;
CStdioFile f1;//定义文件对象
CFileException fileException;//打开失败后的异常处理对象
//打开文件
f1.Open(L"D:\\C Engineering\\Urren\\Release\\ChunGe.txt", CFile::typeText| CFile::modeRead,&fileException);
setlocale(LC_CTYPE, "chs");//加入此设置才能正常读取汉字
f1.ReadString(generd);//把txt文件中的文本全读出来存入generd变量
int ached=generd.Find(L"return");//查找return
ached += 7;//"return"字符串的有多少个字符+一个空格 一共有7个字符,移动7位
generd.Insert(ached,L"2+3");//在指定索引位置插入一个字符串 在return+空格 后面插入2+3
mport.initGlobalContext(); //初始化 msscript.dll
_variant_t urant = "春哥\n";
bool stau = mport.runScriptString(generd, urant);//执行字符串格式的 JS 脚本
estion = urant;
if (stau)
{
WriteConsole(hdlWrite, L"执行成功\n", CString(L"执行成功\n").GetLength(), NULL, NULL); //向DOS窗口里输出字符串
WriteConsole(hdlWrite, estion, CString(estion).GetLength(), NULL, NULL); //向DOS窗口里输出字符串
}
else
{
WriteConsole(hdlWrite, L"执行失败\n", CString(L"执行失败\n").GetLength(), NULL, NULL); //向DOS窗口里输出字符串
}
相当于:(function(){return 2+3;})();
执行后的结果:
经过测试
evalFunction();//执行 JS 脚本中的全局函数
这个方法也是可以用的,想使用此方法需要先加载JS脚本,此方法用于调用已经加载到内存中的JS脚本里的函数,不过此函数无法调用JS对象中的方法,也就是例如:
var ChunGe=new Object()
ChunGe.getName = function(){ return this.name; }
此函数无法调用ChunGe.getName(),而只能调用正常形式的函数例如:
function haha(){}
下面是调用的例子:
CMSJsMgr mport;//CMSJsMgr操作JS的类
CJsArray udgei;//CJsArray是向JS里传参数传用的类
mport.initGlobalContext(); //初始化
CStdioFile f1;//定义文件对象
CFileException fileException;//打开失败后的异常处理对象
f1.Open(L"D:\\C Engineering\\Urren\\Release\\ChunGe.txt", CFile::typeText| CFile::modeRead,&fileException);//打开文件
setlocale(LC_CTYPE, "chs");//加入此设置才能正常读取汉字
f1.ReadString(generd);//把txt文件中的文本全读出来存入generd变量
_variant_t urant = "春哥\n";
bool stau = mport.runScriptString(generd, urant);//执行字符串格式的 JS 脚本
long stion = 10;
long stion_2 = 5;
udgei.pushElement(stion);//压入参数1
udgei.pushElement(stion_2);//压入参数2
//参数1:JS脚本中要执行的函数名;参数2:此JS函数需要的参数;参数3:接收返回值的变量
bool merits = mport.evalFunction(L"kk", &udgei, urant);//执行 JS 脚本中的全局函数
理论上
//参数1:类名;参数2:要调用的类的方法成员;参数3:输入参数的对象;参数4:接收返回值的变量
evalObjFunction()//执行 JS 脚本中某个对象的方法函数
这个方法应该也能用,但没有测试,这个方法就可以调用ChunGe.getName()这样的JS对象里的方法,同样的,使用前需要先加载JS脚本,然后才能调用脚本中的函数。
文中提到的类文件:https://download.csdn.net/download/l198738655/87770918