【发布时间】:2016-02-24 14:22:16
【问题描述】:
各位 SOers,
我正在使用(尝试使用)模板专业化、整数序列和元组的组合来使用可变参数模板从
API,取决于方法签名。我的程序在执行执行此操作的函数时崩溃。谁能告诉我为什么会发生这种情况?我试图绑定签名int(*)(std::string) 的函数。
这里是函数的使用位置/用于绑定的 lambda 的创建位置:
template<typename T_Return, typename ... T_Params>
void bindFunction(T_Return(*function_item)(T_Params ...))
{
std::function<T_Return(T_Params ...)> proxy_func(function_item);
duk_function_t func = [proxy_func] (duk_context* ctx) mutable -> duk_ret_t {
const int n_Args = sizeof...(T_Params);
if(duk_get_top(ctx)==n_Args)
{
if(std::is_same<T_Return, void>::value)
{
detail::duk_get_args<T_Return, T_Params ...>(ctx, proxy_func);
return 0;
}
else
{
detail::duk_return(ctx, detail::duk_get_args(ctx, proxy_func)); //Program crashes in this line
return 1;
}
}
else
{
return 0;
}
};
m_Function = func;
}
程序在代码中的特定点崩溃。
最后,这是我通过模板专业化从 API 检索数据的方法:
template<typename T>
inline T duk_get_arg(duk_context* ctx, int i);
template<>
inline std::string duk_get_arg<std::string>(duk_context* ctx, int i)
{
char* ret_str;
strcpy(ret_str, duk_require_string(ctx, i));
std::string ret(ret_str);
return ret;
}
template<>
inline int duk_get_arg<int>(duk_context* ctx, int i)
{
int ret = duk_require_int(ctx, i);
return ret;
}
template<>
inline unsigned int duk_get_arg<unsigned int>(duk_context* ctx, int i)
{
unsigned int ret = duk_require_int(ctx, i);
return ret;
}
template<>
inline float duk_get_arg<float>(duk_context* ctx, int i)
{
float ret = (float)duk_require_number(ctx, i);
return ret;
}
template<>
inline double duk_get_arg<double>(duk_context* ctx, int i)
{
double ret = duk_require_number(ctx, i);
return ret;
}
template<typename T_Return, typename ... T_Params, size_t ... T_Is>
inline T_Return duk_get_args_impl(duk_context* ctx, std::function<T_Return(T_Params ...)>& function_item, std::index_sequence<T_Is ...>)
{
using tuple_type = std::tuple<T_Params ...>;
T_Return ret;
ret = function_item(duk_get_arg<std::tuple_element_t<T_Is, tuple_type>>(ctx, T_Is) ...);
return ret;
}
template<typename T_Return, typename ... T_Params>
inline T_Return duk_get_args(duk_context* context, std::function<T_Return(T_Params ...)>& function_item)
{
T_Return ret;
ret = duk_get_args_impl<T_Return, T_Params ...>(context, function_item, std::index_sequence_for<T_Params ...>());
return ret;
}
我有什么遗漏/做错了吗?除了以这种方式使用 lambda?我真的希望得到答案,因为我无法弄清楚是什么导致了错误!在此先感谢:)
【问题讨论】:
-
char* ret_str; strcpy(ret_str, duk_require_string(ctx, i));我察觉到了问题 -
事情,是我的回答不能是最小和完整的。我认为这是尽可能少的,正如我所说,绑定工作正常,我只是检查了它执行时包含在 lambda 中的值是否也很好。他们是。所以问题完全在于我对
duk_get_args的实现。 @PiotrSkotnicki 你是什么意思,我在这里做错了吗?我正在将 constchar*复制到char*。 -
@calcyss 您的问题绝对可以是最小的和完整的。只要继续删除东西,直到你可以产生自给自足的东西,仍然会重现错误。很有可能,只要这样做,您就会自己发现问题。照原样,这只是一段代码,其中许多函数未定义,Piotr 碰巧注意到了其中的一个问题。这不是真正获得帮助的好方法。
-
@calcyss 这个问题可以最小化。对于每一行,如果删除它,错误是否仍然发生?
std::cout << "wrong number of arguments! retreating!" << std::endl;我敢打赌,删除该行仍然会使代码崩溃,我花了 5 秒钟才找到。要么您无法删除代码行,要么您没有尝试?完成该过程后,您就可以处理逻辑了——您可以跳过整个逻辑层来重现问题吗?找出崩溃发生的位置,只重现那行代码并重现崩溃?是的,这需要工作。
标签: c++ templates c++11 lambda c++14