¿Cómo puedo pasar una función de C++ generada dinámicamente como *funcprt a una API de C?
La API exporta esto:
DllImport void api_register_func(char *func_name, void (*funcptr)(char *, char *));Tengo que crear la función durante el tiempo de ejecución porque no la conozco antes. Entonces usé una clase:
class JsFunc { public: char * JsFuncName; char * JsParameter; void RunFunc(char * val1, char * val2) { printf("\nJsFunc.runFunc executed, JsParameter=%s passed\n",JsParameter); } };Y llámalo así:
JsFunc * jsm = new JsFunc (); jsm->JsFuncName = external_parameter1; jsm->JsParameter = external_parameter2; api_register_func(external_parameter1, jsm->RunFunc);Pero VisualStudio 2015 me dice:
Error C3867 'JsFunc::runFunc': sintaxis no estándar; use '&' para crear un puntero al miembro VJCS C:\Users\astrauss\Source\Repos\VCJS\VCJS\VCJS.cpp 54
Lo siento si el código es malo, no soy un programador de C/C++ pero necesito que esto funcione para mi trabajo diario. ¡Gracias!
Desafortunadamente, no tienes muchas opciones aquí. La API:
DllImport void api_register_func(char *func_name, void (*funcptr)(char *, char *));solo le permite proporcionar un puntero de función, sin ningún contexto. Entonces puede pasar una función libre o una función de miembro estática, pero no tiene forma de proporcionar una función de miembro. Si tuvieras un contexto:
DllImport void better_api_register_func(char *func_name, void *context, void (*funcptr)(void *, char *, char *));Entonces podrías escribir una lambda simple:
api_register_func(external_parameter1, jsm, //context [](void *ctxt, char* arg1, char* arg2) { static_cast<JsFunc*>(ctxt)->runFunc(arg1, arg2); });y está utilizando efectivamente una función miembro como devolución de llamada. Sin embargo, esta no es una opción. En cambio, está atascado con el uso de una variable global:
std::unique_ptr<JsFunc> the_global_func;Que puede asignar en tiempo de ejecución:
the_global_func.reset(new JsFunc); // set stuffY luego usa el global en una lambda. Dado que es global, no necesitamos (de hecho, no podemos) capturarlo, lo que significa que nuestro lambda puede convertirse en un puntero de función:
api_register_func(external_paramter1, [](char* arg1, char* arg2) { the_global_func->runFunc(arg1, arg2); });