如何将函数从c++类传递到C API

Howto pass funcptr from C++ Class to a C API?

本文关键字:API c++ 函数      更新时间:2023-10-16

如何将动态生成的c++函数作为*funcprt传递给C API?

API导出这个:

DllImport void api_register_func(char *func_name, void (*funcptr)(char *, char *));

我必须在运行时创建函数,因为我之前不知道它。所以我使用了一个类:

class JsFunc
{
    public:
        char * JsFuncName;
        char * JsParameter;
    void RunFunc(char * val1, char * val2)
    {
        printf("nJsFunc.runFunc executed, JsParameter=%s passedn",JsParameter);
    }
};

然后这样命名:

JsFunc * jsm = new JsFunc ();
jsm->JsFuncName = external_parameter1; 
jsm->JsParameter = external_parameter2; 
api_register_func(external_parameter1, jsm->RunFunc);

但是VisualStudio 2015告诉我:

错误C3867 'JsFunc::runFunc':非标准语法;使用'&'来创建一个指向成员VJCS c: users aus source repository vcjs vcjs vcjs .cpp 54

对不起,如果代码不好,我不是一个C/c++程序员,但需要得到这个运行为我的日常工作。谢谢!

不幸的是,您在这里没有太多选择。API:

DllImport void api_register_func(char *func_name, 
                                 void (*funcptr)(char *, char *));

只允许您提供函数指针,而不提供任何上下文。所以你可以传入一个自由函数或者静态成员函数,但是你没有办法提供一个成员函数。如果你有一个上下文:

DllImport void better_api_register_func(char *func_name, 
                                        void *context,
                                        void (*funcptr)(void *, char *, char *));

你可以写一个简单的lambda:

api_register_func(external_parameter1,
                  jsm, //context
                  [](void *ctxt, char* arg1, char* arg2) {
                      static_cast<JsFunc*>(ctxt)->runFunc(arg1, arg2);
                  });

,你实际上是在使用一个成员函数作为回调。然而,这不是一个选择。相反,您只能使用全局变量:

std::unique_ptr<JsFunc> the_global_func;

可以在运行时分配:

the_global_func.reset(new JsFunc);
// set stuff

然后在lambda中使用全局变量。因为它是全局的,我们不需要(事实上,不能)捕获它——这意味着我们的lambda可以转换为函数指针:

api_register_func(external_paramter1,
                  [](char* arg1, char* arg2) {
                      the_global_func->runFunc(arg1, arg2);
                  });