Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何通过C++;指向预定义C函数的函数指针(非静态成员函数)?_C++_C_Templates_Function Pointers - Fatal编程技术网

C++ 如何通过C++;指向预定义C函数的函数指针(非静态成员函数)?

C++ 如何通过C++;指向预定义C函数的函数指针(非静态成员函数)?,c++,c,templates,function-pointers,C++,C,Templates,Function Pointers,我正在考虑使用中的库,它是用C编写的 但是,我将其包含在一个成员函数“dlevmar__der”中,该函数需要两个函数指针作为其参数: int dlevmar_der( void (*func)(double *p, double *hx, int m, int n, void *adata), void (*jacf)(double *p, double *j, int m, int n, void *adata), double *p, /* I

我正在考虑使用中的库,它是用C编写的

但是,我将其包含在一个成员函数“dlevmar__der”中,该函数需要两个函数指针作为其参数:

int dlevmar_der(
    void (*func)(double *p, double *hx, int m, int n, void *adata), 
    void (*jacf)(double *p, double *j, int m, int n, void *adata),  
    double *p,         /* I/O: initial parameter estimates. On output contains the estimated solution */
    double *x,         /* I: measurement vector. NULL implies a zero vector */
    int m,             /* I: parameter vector dimension (i.e. #unknowns) */
    int n,             /* I: measurement vector dimension */
    int itmax,         /* I: maximum number of iterations */
    double opts[4],
    double info[LM_INFO_SZ],
    double *work,
    double *covar,
    void *adata
)
我有以下简化的模板类,其中包含两个非静态成员函数CallBack和MyJac。(假设我在类中还有所有其他属性m_solution、m_info等):

模板
类MyClass
{
公众:
typedef void(MyClass::*FuncPtrType)(float*);
void Start()
{
此->运行(&MyClass::MyJac);
}
受保护的:
void回调(ValueType x[],ValueType result[],int m,int n,void*adata){//some code}
void MyJac(ValueType x[],ValueType result[],int m,int n,void*adata){//some code}
无效运行(FuncPtrType func)
{
int iterCount=dlevmar\u der(&MyClass::Callback,func,
(双*)&此->m_解决方案[0],
(双*)和零[0],
此->m_函数.NumberOfParameters,
此->m_function.NumberOfFunctionValues,
这->m_maxIterations,
这个->m_选项,
这个->m_信息,
无效的
无效的
静态_cast(this));
}
}
但是,当调用
Start()
函数时,我在“Run”函数中遇到一个错误,它说:
错误C2664:'slevmar\u der':无法从'void(u thiscall MyClass:::::*)(float*,float*,int,int,void*)转换为'void(u cdecl*)(float*,float*,int,void*)


我的问题是
dlevmar\u der
函数是否只能获取指向静态成员函数的函数指针?或者有什么方法可以将非静态成员函数用于
dlevmar\u der
实现?

您需要构建一个蹦床函数

只需将
this
作为
adata
参数传递,然后编写一个回调函数,将
adata
回调到正确的类型指针并调用该方法。例如:

  void myFunc(double *p, double *hx, int m, int n, void *adata) {
      MyClass *self = static_cast<MyClass>(adata);
      self->funcMethod(p, hx, m, n, self->func_adata);
  }
void myFunc(double*p,double*hx,int m,int n,void*adata){
MyClass*self=静态投影(adata);
self->func方法(p,hx,m,n,self->func_adata);
}
编写一个静态包装器

template<class F> 
class MyClass
{
    protected:
        void Callback(ValueType x[], ValueType result[], int m, int n) { 

        }

        static void CallbackWrapper(
              ValueType x[], ValueType result[], int m, int n, 
              void* adata) 
        { 
            static_cast<MyClass<T>*>(adata)->Callback(x, result, m, n);
        }

        void Run(FuncPtrType func)
        {
             int iterCount = dlevmar_der(
                 &MyClass<F>::CallbackWrapper, /*..*/ );
        }
};
模板
类MyClass
{
受保护的:
无效回调(ValueType x[],ValueType result[],int m,int n){
}
静态无效回调包装器(
ValueType x[],ValueType结果[],int m,int n,
void*adata)
{ 
静态_cast(adata)->回调(x,result,m,n);
}
无效运行(FuncPtrType func)
{
int iterCount=dlevmar\u der(
&MyClass::CallbackWrapper,/*..*/);
}
};

C++成员函数指针不能与常规函数指针互换使用

但是,在需要C函数指针的地方,通常可以安全地使用静态成员函数指针。您的C API似乎允许您将自己的
void*
上下文参数传递给回调。您可以使用它将实例指针传递回一个静态方法,并使用它来调用isntance方法,如下所示:

static void StaticCallback(/* Args... */, void *user_data)
{
    MyClass *ptr = static_cast<MyClass*>(user_data);
    ptr->NonStaticCallback(/*args...*/);
}
static void StaticCallback(/*Args…*/,void*用户数据)
{
MyClass*ptr=静态广播(用户数据);
ptr->非静态回调(/*args…*/);
}

(严格来说,您需要使用声明为
extern“C”
的自由(非成员)函数进行转发,但静态方法通常是可以的。)

是的,在需要自由(非成员)或静态成员函数的情况下,不能使用指向(非静态)成员函数的指针。静态函数没有
this
。你可能是指
adata
static void StaticCallback(/* Args... */, void *user_data)
{
    MyClass *ptr = static_cast<MyClass*>(user_data);
    ptr->NonStaticCallback(/*args...*/);
}