C++调用 gsl gsl_integration.h 积分 - V2EX
zhouzhou113
V2EX    C

C++调用 gsl gsl_integration.h 积分

  •  
  •   zhouzhou113 Feb 5, 2018 3309 views
    This topic created in 3021 days ago, the information mentioned may be changed or developed.

    ubuntu 下使用 C++编程,调用 gsl 积分库,被积函数作为成员函数,定义如下:

    double planning::f(double x, void * params) {

    double alpha = *(double *)params; double f = pow(x, 4)*sin(0.3*x + 0.12194239*pow(x, 2)); return f; 

    }

    在另一个成员函数中拷贝该函数指针以调用积分计算函数,如下:

    void planning::GpsCallback(const GpsImu7661::ivsensorgps::ConstPtr& in) {

    gsl_set_error_handler_off(); gsl_integration_workspace * w= gsl_integration_workspace_alloc(1000); double result, error; double expected = -4.0; double alpha = 1.0; gsl_function F; //*****************************// F.function = &f; //F.function = &planning::f; F.params = α int fanhui = gsl_integration_qags(&F, 0, 82.16478, 0, 1e-7, 1000, w, &result,&error); if (0 == gsl_integration_qags(&F, 0, 82.16478, 0, 1e-7, 1000,w, &result, &error)){ printf("result = % .18f\n", result); printf("estimated error = % .18f\n", error); printf("intervals = %zu\n", w->size); } gsl_integration_workspace_free(w); 

    }

    *下语句报错如下: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function.

    百度错误之后修改为 F.function = &planning::f;
    报错变成了:error: cannot convert ‘ double (planning::)(double, void)’ to ‘ double ()(double, void)’ in assignment

    有没有在成员函数中调用过 gsl 函数库的大神,,有什么解决方法吗?

    Supplement 1    Feb 5, 2018
    补充一下下
    planning 是类

    调用的 gsl-2.4 版本库

    gsl_function 来自 gsl_math.h 头文件:
    typedef struct gsl_function_struct gsl_function ;

    包含了以下头文件:
    #include <gsl/gsl_integration.h>
    #include <gsl/gsl_errno.h>
    #include "gsl/gsl_sf_gamma.h"

    不好意思,问题方式不够谨慎,造成困扰。。
    19 replies    2018-02-06 12:25:17 +08:00
    MeteorCat
        1
    MeteorCat  
       Feb 5, 2018 via Android
    planning 是类?如果是的话 F.function = &this->f 作为传递一个内部函数指针是会提示非静态,建议试下直接使用用函数方式,或者把 f 设为静态成员
    MeteorCat
        2
    MeteorCat  
       Feb 5, 2018 via Android
    稍等下,我本地测试一下使用方式,看下是否我的方式是否可用
    GeruzoniAnsasu
        3
    GeruzoniAnsasu  
       Feb 5, 2018
    F.function = [this](double x,void *param){return f(x,param);};
    或者
    F.function = std::bind(f,this,std::placeholders::_1,std::placeholders::_2);
    GeruzoniAnsasu
        4
    GeruzoniAnsasu  
       Feb 5, 2018
    看报错 F.function 应该是个 callable,比如 std::function<double(double,void*)>之类的东西,构造这种东西要么就用 lambda,要么就 functor (重载了()运算符的类),bind 就是用模板构造一个 functor 的方法,但其实现原理相当相当复杂,特别是,如何使 functor 绑定到类成员函数上。用 lambda 就容易理解得多,闭包捕获是世界上所有能进行 functional programing 的语言都通用的语义,把 this 指针捕获进闭包中,然后返回这个闭包。虽说会多出一层显式的调用 wrapping,不过这个 lambda 几乎一定会被优化掉,所以也不用担心这个问题
    MeteorCat
        5
    MeteorCat  
       Feb 5, 2018
    3 楼正确,请楼主下次代码能否贴全?我在编写测试时代的时候一堆报错,我以为是我库链接问题,排查了一遍库文件;又以为是我库版本太老了,更新一遍链接库;而且`gsl_function`到底是函数指针还是`std::function`,我认为楼主在提问上面还需要审慎一下
    innoink
        6
    innoink  
       Feb 5, 2018 via Android
    非静态成员函数需要一个 this 指针参数,所以实际的函数指针类型要么是 ret classname::func(args)要么是 ret func(this, args),你这么转当然会出错
    解决方法:构造一个严格的 double ()(double, void*)(非成员函数,或者静态成员函数),把你的 f 包装进去。
    justou
        7
    justou  
       Feb 5, 2018
    gsl_function 里 function 的签名必须是 double(double, void*)这样的一个纯 C 函数, 不是任何 C++特有的对象.

    struct gsl_function_struct
    {
    double (* function) (double x, void * params);
    void * params;
    };

    typedef struct gsl_function_struct gsl_function ;

    毕竟 gsl 是个 C 库
    innoink
        8
    innoink  
       Feb 5, 2018 via Android
    还有,很好奇 double alpha = *(double *)params;这是在干嘛
    justou
        9
    justou  
       Feb 5, 2018
    @innoink 把 void* cast 成 double*, 再解引用
    innoink
        10
    innoink  
       Feb 5, 2018 via Android
    @justou 但是后面也没用到啊
    justou
        11
    justou  
       Feb 5, 2018
    @innoink 他代码问题, 我猜测是 0.12194239 这个参数 →_→
    MeteorCat
        12
    MeteorCat  
       Feb 5, 2018
    @innoink 我也感觉,我 llvm 编译的开启`-Wunused-variable`的时候也是爆出这个局部 unused,可能是为了隐私而删除掉代码;说实话,我很讨厌这种提问风格,排查问题还需要我们一起来猜某个变量或者某个函数的作用和功能
    lanry
        13
    lanry  
       Feb 5, 2018
    planning::f 定义成 static 方法就 ok 了,看上去也没必要定义成 non-static
    zhouzhou113
        14
    zhouzhou113  
    OP
       Feb 5, 2018
    double alpha = *(double *)params;
    double alpha = 1.0;
    F.params = &alpha;
    上三句没有具体用到,
    源码是 c 编写,想运用到 C++的成员函数中,

    除了类 planning,以及这两个成员函数是我自己定义的:
    double planning::f(double x, void * params)
    void planning::GpsCallback(const GpsImu7661::ivsensorgps::ConstPtr& in)

    函数体中的变量函数都对应 gsl 库
    gnaggnoyil
        15
    gnaggnoyil  
       Feb 5, 2018
    要是 LZ 对如何把一个 invocable object 给塞进一个函数中这个问题想不明白的话,可以想想标准库中的 std::thread 是怎么实现的……
    innoink
        16
    innoink  
       Feb 5, 2018
    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    class base{
    public:
    void test()
    {
    printf("void test();\n");
    }
    };
    int main(int argc,char **argv)
    {
    base b;
    typedef void (*cfp)(base *);
    auto x = &base::test;

    cfp c;
    memcpy(&c, &x, sizeof(c));
    c(&b);
    }

    在标准 c++中将非静态成员函数转成 c 风格(即,不是 b.*x 这种形式)的函数指针的唯一方式(如果有其他方式请告诉我)
    innoink
        17
    innoink  
       Feb 5, 2018
    @innoink 当然,memcpy 可以改成*((long*)&c) = *((long*)&x);
    Jerrymouse1
        18
    Jerrymouse1  
       Feb 5, 2018
    将那个 f 方法定义为 static,应该能行
    hackpro
        19
    hackpro  
       Feb 6, 2018
    建议按照
    @GeruzoniAnsasu #3 的做法
    否则你需要解决函数指针和类成员变量的签名问题
    About     Help     Advertise     Blog     API     FAQ     Solana     5514 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 54ms UTC 09:04 PVG 17:04 LAX 02:04 JFK 05:04
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86