通过引用 C++ 代码中的 Qore 脚本函数来传递值
Passing value by reference to Qore script function from C++ code
我需要将 returnValue 作为按引用传递的参数传递给方法,并在函数 ID 完成后调整原始 var 值。所以使用 ReferenceArgumentHelper class。
当 returnValue 被无意删除(当它是一个节点,即字符串)并且 valgrind 检测到它时,下面的代码有什么问题。 callMethod("onFunctionExit" 调用 Qore 脚本方法,我可以看到正确的 returnValue 值。我怀疑它在退出时被删除 onFunctionExit当ReferenceArgumentHelper被销毁时,rah.getArg()引用引用变量,所以不应该被删除在 callMethod.
DLLLOCAL ThreadDebugEnum callMethod(const char* name, const ThreadDebugEnum defaultResult, QoreProgram *pgm, int paramCount, AbstractQoreNode** params, ExceptionSink* xsink) {
int rv;
QoreListNode* l = new QoreListNode();
qore_program_to_object_map_t::iterator i = qore_program_to_object_map.find(pgm);
if (i == qore_program_to_object_map.end()) {
return defaultResult;
}
i->second->ref();
l->push(i->second);
for (int i=0; i<paramCount; i++) {
if (params[i])
params[i]->ref();
l->push(params[i]);
}
rv = qo->intEvalMethod(name, l, xsink);
l->deref(xsink);
return (ThreadDebugEnum) rv;
}
DLLLOCAL virtual ThreadDebugEnum onFunctionExit(QoreProgram *pgm, const StatementBlock *blockStatement, QoreValue& returnValue, ExceptionSink* xsink) {
AbstractQoreNode* params[2];
params[0] = getLocation(blockStatement);
ReferenceArgumentHelper rah(returnValue.takeNode(), xsink); // grab node from returnValue and pass to helper
params[1] = rah.getArg(); // caller owns ref
ThreadDebugEnum rv = callMethod("onFunctionExit", DBG_SB_RUN, pgm, 2, params, xsink);
AbstractQoreNode* rc = rah.getOutputValue(); // caller owns ref
returnValue.assign(rc); // takes reference
// returnValue.ref();
}
return rv;
}
当深入观察时,我不明白为什么编译器对 /lib/ReferenceArgumentHelper.cpp:
中的代码感到满意
struct lvih_intern {
LocalVar lv;
ExceptionSink* xsink;
ReferenceNode* ref;
DLLLOCAL lvih_intern(AbstractQoreNode* val, ExceptionSink* xs) : lv("ref_arg_helper", 0), xsink(xs) {
printd(5, "ReferenceArgumentHelper::ReferenceArgumentHelper() instantiating %p (val: %p type: '%s') \n", &lv, val, val ? val->getTypeName() : "n/a");
lv.instantiate(val); <--------------
VarRefNode* vr = new VarRefNode(strdup("ref_arg_helper"), VT_LOCAL);
vr->ref.id = &lv;
ref = new ReferenceNode(vr, 0, vr, 0);
}
class LocalVar {
....
DLLLOCAL void instantiate(QoreValue nval) const {
在方法调用中将 AbstractQoreNode* 转换为 QoreValue 的背后是什么?我没有找到重载的运算符。我正在查看引用到底发生了什么。
** 编辑 **
长话短说,ReferenceArgumentHelper
有很多问题;它已多年未使用,也不是最新的。 class 已修复,希望能解决您的问题。
感谢您指出这一点,如果您对此有任何进一步的问题或受影响代码的修复,请告诉我。
我需要将 returnValue 作为按引用传递的参数传递给方法,并在函数 ID 完成后调整原始 var 值。所以使用 ReferenceArgumentHelper class。
当 returnValue 被无意删除(当它是一个节点,即字符串)并且 valgrind 检测到它时,下面的代码有什么问题。 callMethod("onFunctionExit" 调用 Qore 脚本方法,我可以看到正确的 returnValue 值。我怀疑它在退出时被删除 onFunctionExit当ReferenceArgumentHelper被销毁时,rah.getArg()引用引用变量,所以不应该被删除在 callMethod.
DLLLOCAL ThreadDebugEnum callMethod(const char* name, const ThreadDebugEnum defaultResult, QoreProgram *pgm, int paramCount, AbstractQoreNode** params, ExceptionSink* xsink) {
int rv;
QoreListNode* l = new QoreListNode();
qore_program_to_object_map_t::iterator i = qore_program_to_object_map.find(pgm);
if (i == qore_program_to_object_map.end()) {
return defaultResult;
}
i->second->ref();
l->push(i->second);
for (int i=0; i<paramCount; i++) {
if (params[i])
params[i]->ref();
l->push(params[i]);
}
rv = qo->intEvalMethod(name, l, xsink);
l->deref(xsink);
return (ThreadDebugEnum) rv;
}
DLLLOCAL virtual ThreadDebugEnum onFunctionExit(QoreProgram *pgm, const StatementBlock *blockStatement, QoreValue& returnValue, ExceptionSink* xsink) {
AbstractQoreNode* params[2];
params[0] = getLocation(blockStatement);
ReferenceArgumentHelper rah(returnValue.takeNode(), xsink); // grab node from returnValue and pass to helper
params[1] = rah.getArg(); // caller owns ref
ThreadDebugEnum rv = callMethod("onFunctionExit", DBG_SB_RUN, pgm, 2, params, xsink);
AbstractQoreNode* rc = rah.getOutputValue(); // caller owns ref
returnValue.assign(rc); // takes reference
// returnValue.ref();
}
return rv;
}
当深入观察时,我不明白为什么编译器对 /lib/ReferenceArgumentHelper.cpp:
中的代码感到满意struct lvih_intern {
LocalVar lv;
ExceptionSink* xsink;
ReferenceNode* ref;
DLLLOCAL lvih_intern(AbstractQoreNode* val, ExceptionSink* xs) : lv("ref_arg_helper", 0), xsink(xs) {
printd(5, "ReferenceArgumentHelper::ReferenceArgumentHelper() instantiating %p (val: %p type: '%s') \n", &lv, val, val ? val->getTypeName() : "n/a");
lv.instantiate(val); <--------------
VarRefNode* vr = new VarRefNode(strdup("ref_arg_helper"), VT_LOCAL);
vr->ref.id = &lv;
ref = new ReferenceNode(vr, 0, vr, 0);
}
class LocalVar {
....
DLLLOCAL void instantiate(QoreValue nval) const {
在方法调用中将 AbstractQoreNode* 转换为 QoreValue 的背后是什么?我没有找到重载的运算符。我正在查看引用到底发生了什么。
** 编辑 **
长话短说,ReferenceArgumentHelper
有很多问题;它已多年未使用,也不是最新的。 class 已修复,希望能解决您的问题。
感谢您指出这一点,如果您对此有任何进一步的问题或受影响代码的修复,请告诉我。