Fellow SOers,
i hate to ask questions like this. But, for the love of god, i can't figure out what the problem is. Im using a combination of template specialization, integer sequences and tuples to use variadic templates to retrieve parameters from an api, depending on the method signature. My program crashes when executing the function that does just this. Can anybody give me a hint as to why this could happen? This is the function im trying to "bind":
int cnum(std::string str)
{
std::cout << "\"" << str << "\"" << std::endl;
return std::stoi(str) * 2;
}
Im binding it to the JavaScript interpreter via the means of templated lambdas. I understand that this might not be the best way, but it works. And its apparently not the cause of the issue, as using the lambda itself works, its just a function within the lambda that crashes. Here is where the function is used/where the lambda used for binding is created:
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 {
std::cout << "i got executed." << std::endl;
const int n_Args = sizeof...(T_Params);
if(duk_get_top(ctx)==n_Args)
{
std::cout << "correct number of arguments! advancing!" << std::endl;
if(std::is_same<T_Return, void>::value)
{
std::cout << "return value is void. executing now." << std::endl;
detail::duk_get_args<T_Return, T_Params ...>(ctx, proxy_func);
return 0;
}
else
{
std::cout << "return value is " << typeid(T_Return).name() << ". executing now." << std::endl;
detail::duk_return(ctx, detail::duk_get_args(ctx, proxy_func)); //Program crashes in this line
return 1;
}
}
else
{
std::cout << "wrong number of arguments! retreating!" << std::endl;
return 0;
}
};
m_Function = func;
}
As seen in the comment, when executing the function from within the interpreter (which means the binding itself is working) i get the following output:
adding proxy function with address 0xc1f1e0.
name: cnum
address of handleFunction: 0x401a7a. <-- those are some diagnostic/debugging values to check if everything is alright with the functions.
>> cnum("3");
executing function with address 0xc1f1e0.
i got executed.
correct number of arguments! advancing!
return value is i(int). executing now.
*CRASH*
And lastly, here is how i retrieve data from the API via templates:
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;
}
Is there anything i am missing/doing fundamentally wrong? Except for using lambdas this way? I really do hope for an answer, since i cant make out what is causing the error! Thanks in advance :)
Aucun commentaire:
Enregistrer un commentaire