欢迎光临散文网 会员登陆 & 注册

利用std::shared_ptr 回收不同类型对象的内存

2023-05-16 22:44 作者:卢朓  | 我要投稿

/**
 * 北太天元的插件开发示例,
 * 每次介绍很少的几个知识点,面向的对象是对c++11之后的特性不熟悉的同学。
 * 这一次是增加了用 std::shared_ptr<void> 回收不同类型对象的内存的功能
 */

#include <memory>
#include <cstdlib>
#include <iostream>
#include <typeinfo>
#include <utility>
#include <array>
#include <map>
#include <vector>
#include "bex/bex.hpp"

namespace ParseParams {
    template <class _T>
        class FunTrait;
    template <typename R, typename... Args>
        class FunTrait<R(Args...)>{
            public:
                static constexpr size_t n_args = sizeof...(Args);
                static constexpr const std::array<const std::type_info *, n_args> infos = {&typeid(Args)...};
            
            public:
            int required_params;
            std::vector<std::shared_ptr<void>> trash_bin;
            std::array<void *, n_args> passed_args_ptr;
            //变量类型函数句柄, 变量名是decorated_func
            R(*decorated_func)
                (Args...);


            public:
            FunTrait(R (*func)(Args...), int num_required = 0){
                decorated_func = func;
              required_params = num_required;
            }

            template <size_t... I>
            R eval_impl(std::index_sequence<I...>){
                std::cout<<"必须的参数个数是 = " << required_params << std::endl;
                return decorated_func((Args)passed_args_ptr[I]...);
            }

            R eval(){
                return eval_impl(std::make_index_sequence<n_args>());
            }

            int check_in_args_type(int nrhs, const bxArray * prhs[]){
                for(size_t i= 0; i< n_args; i++){
                    if(infos[i]->name() == typeid(const double *).name()){
                        if(!bxIsDouble(prhs[i])){
                            bxPrintf("第%d输入参数必须是double类型",i);
                            return 1;
                        }
                        passed_args_ptr[i] = (void *)(bxGetDoubles(prhs[i]));
                    }    
                    else if(infos[i]->name() == typeid(const int32_t *).name()){
                        if(!bxIsInt32(prhs[i])){
                            bxPrintf("第%d输入参数必须是int32类型",i);
                            return 1;
                        }
                        passed_args_ptr[i] = (void *)(bxGetInt32s(prhs[i]));
                    }    
                    else if(infos[i]->name() == typeid(const int64_t *).name()){
                        if(!bxIsInt64(prhs[i])){
                            bxPrintf("第%d输入参数必须是int64类型",i);
                            return 1;
                        }
                        passed_args_ptr[i] = (void *)(bxGetInt64s(prhs[i]));
                    }    
                    else if(infos[i]->name() == typeid(const std::string *).name()){
                        if(!bxIsString(prhs[i])){
                            bxPrintf("第%d输入参数必须是string类型",i);
                            return 1;
                        }
                        passed_args_ptr[i] = (void *)(new std::string(bxGetStringDataPr(prhs[i])));
                        trash_bin.push_back(std::shared_ptr<std::string>((std::string *)passed_args_ptr[i]));
                    }
                    else {
                            bxPrintf("第%d输入参数类型不对",i);
                            return 1;
                    }
                }
                return 0;
            }

            void return_to_bxArray(R result, int nlhs, bxArray *plhs[]){
                if(nlhs <= 0 ) return;
                if constexpr (std::is_same<char, R>::value){
                    char tmp[2] ={result, '\0'};
                    plhs[0] = bxCreateString(tmp);    
                }    
                else if constexpr (std::is_same<int32_t,R>::value){
                    plhs[0] = bxCreateInt32Scalar(result);
                }
                else if constexpr (std::is_same<double,R>::value){
                    plhs[0] = bxCreateDoubleMatrix(1,1,bxREAL);
                    double * ptr = bxGetDoubles(plhs[0]);
                    *ptr = result;
                }    
                else if constexpr (std::is_same<std::string,R>::value){
                    plhs[0] = bxCreateString(result.c_str());
                }
            }

        };
}


char h(const int *j , const std::string  *str ){
    std::cout<<" *j = "<<*j << std::endl;
    std::cout<<" *str = "<<*str << std::endl;
    std::cout<<" (*str)[*j] = "<<(*str)[*j]<< std::endl;
    return (*str)[*j];
}

void cmd_h(int nlhs, bxArray *plhs[], int nrhs, const bxArray *prhs[]) {
    ParseParams::FunTrait<decltype(h)> q(h,0);
    if(nrhs < q.n_args ){
        bxPrintf("输入参数%d < %d", nrhs, q.n_args);
        return;
    }    
    if(0 != q.check_in_args_type(nrhs, prhs)){
        bxPrintf("输入参数赋值出错\n");
        return;
    }
    auto result = q.eval();
    q.return_to_bxArray(result, nlhs, plhs);

}


static bexfun_info_t flist[] = {
  {"cmdd_h", cmd_h, nullptr},
  {"", nullptr, nullptr},
};

bexfun_info_t *bxPluginFunctions() {
  return flist;
}


利用std::shared_ptr 回收不同类型对象的内存的评论 (共 条)

分享到微博请遵守国家法律