函数是 script 中的一等公民。
在 C++ 中调用 script 中的函数练习一
- script 定义一个匿名的对象,其func属性是一个函数。
在C++代码中:
- evaluate() 的结果是该对象
- 取其 func 属性
- 调用该函数
这儿涉及的始终是 QScriptValue !
#include /QCoreApplication>
#include /QDebug>
#include
const char script[]="({\n"
" func: function(x){return x*100}\n"
"})\n";
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QScriptEngine engine;
QScriptValue object = engine.evaluate(script);
QScriptValue func = object.property("func");
QScriptValue res = func.call(object, QScriptValueList()<<10);
if (engine.hasUncaughtException()){
qDebug()<<engine.uncaughtException().toString();
qDebug()<<engine.uncaughtExceptionBacktrace().join("\n");
} else {
qDebug()<<res.toNumber();
}
return a.exec();
}
练习二
C++ 代码中:
- evaluate() 该脚本
- 通过 engine.globalObject() 的属性获得该函数
- 调用函数(传递给对象的是一个无效的 QScriptValue())
#include /QCoreApplication>
#include /QDebug>
#include
const char script[]="function func(x){return x*100}\n";
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QScriptEngine engine;
engine.evaluate(script);
QScriptValue func = engine.globalObject().property("func");
QScriptValue res = func.call(QScriptValue(), QScriptValueList()<<10);
if (engine.hasUncaughtException()){
qDebug()<<engine.uncaughtException().toString();
qDebug()<<engine.uncaughtExceptionBacktrace().join("\n");
} else {
qDebug()<<res.toNumber();
}
return a.exec();
}
导出C++中定义的函数script 中的 this
script 中的 this 与 C++中的有本质的区别。函数调用方式决定了this对象究竟是哪个对象。
下面一段script的代码:
var func = function(k){return k*this["val"]}
var val = 100
print(func(20))
var obj = {val:200}
print(func.call(obj, 20))
obj.f = func
print(obj.f(20))
3次调用的输出是
2000
4000
4000在C++ 中定义该函数
考虑一下:Script 中的这个函数,在C++中如何定义,并导出到 script 环境中。
var func = function(k){return k*this["val"]}
函数定义需要遵循一个统一的格式(还有一个3参数的,见Manual)
QScriptValue f(QScriptContext *, QScriptEngine *)
context 提供了函数中所需要的参数,以及this对象。
QScriptValue cppFunc(QScriptContext *ctx, QScriptEngine *eng)
{
int k = ctx->argument(0).toNumber();
int v = ctx->thisObject().property("val").toNumber();
return k*v;
}完整代码
- 定义函数
- 用 engine.newFunction 进行封装
- 通过 engine.globalObject() 导出到Script脚本环境
#include /QCoreApplication>
#include /QDebug>
#include
const char script[]="var val = 100\n"
"print(func(20))\n"
"var obj = {val:200}\n"
"print(func.call(obj, 20))\n"
"obj.f = func\n"
"print(obj.f(20))";
QScriptValue cppFunc(QScriptContext *ctx, QScriptEngine *eng)
{
int k = ctx->argument(0).toNumber();
int v = ctx->thisObject().property("val").toNumber();
return k*v;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QScriptEngine engine;
QScriptValue func = engine.newFunction(cppFunc);
engine.globalObject().setProperty("func", func);
engine.evaluate(script);
if (engine.hasUncaughtException()){
qDebug()<<engine.uncaughtException().toString();
qDebug()<<engine.uncaughtExceptionBacktrace().join("\n");
}
return a.exec();
}
错误与异常
| script | c++ |
参数个数 | arguments.length | ctx->argumentCount() |
参数类型(比如number) | typeof arguments[0] != "number" | ctx->argument(0).isNumber() |
抛出异常 | throw Error("...") throw TypeError("...") | ctx->throwError(QScriptContext::TypeError, "...") ... |
阅读(2969) | 评论(0) | 转发(0) |