我可以使用C程序中的C ++模板库吗?

时间:2022-09-07 07:58:41

My knowledge of C++ is limited. I understand that C++ libraries can be called from C provided a C interface is available. Is it possible to call a C++ template library defined in a .hpp file from a C library? For example, this wonderful expression evaluation library.

我对C ++的了解有限。据我所知,只要C接口可用,就可以从C调用C ++库。是否可以从C库调用.hpp文件中定义的C ++模板库?例如,这个精彩的表达评估库。

It may be time to learn C++! OK. Here is a first try:

可能是学习C ++的时候了!好。这是第一次尝试:

#ifndef EXPRTK_C_H_
#define EXPRTK_C_H_
#include "exprtk.hpp"

//Header
#ifdef __cplusplus
extern "C" {
#endif

typedef exprtk::symbol_table<double>      symbol_table_t;
typedef exprtk::expression<double>          expression_t;
typedef exprtk::parser<double>                  parser_t;

  void add_variable_(symbol_table_t st, char* name, double *value);
  void register_symbol_table_(expression_t ex, symbol_table_t st);
  void compile_(parser_t parser, char *expression_string, expression_t ex);
  double evaluate_(expression_t ex);

#ifdef __cplusplus
}
#endif

#endif /* EXPRTK_C_H_ */


#include "exprtk.hpp"
#include "exprtk_c.hpp"

Here is the .cpp file. trig_function() is the real example, used in main(). What follows is my attempt at wrapping the functions. Error message is with parser.

这是.cpp文件。 trig_function()是main()中使用的真实示例。接下来是我尝试包装这些功能。错误消息是解析器。

exprtk.hpp:16962:7: error: ‘exprtk::parser<T>::parser(const exprtk::parser<T>&) [with T = double]’ is private
exprtk_simple_example_01.cpp:85:83: error: within this context
exprtk_simple_example_01.cpp:60:6: error:   initializing argument 1 of ‘void compile_(parser_t, char*, expression_t)’

template<typename T>
void trig_function() {
    std::string expression_string =
            "clamp(-1.0,sin(2 * pi * x) + cos(x / 2 * pi),+1.0)";
    T x;
    exprtk::symbol_table<T> symbol_table;
    symbol_table.add_variable("x", x);
    symbol_table.add_constants();

    exprtk::expression<T> expression;
    expression.register_symbol_table(symbol_table);

    exprtk::parser<T> parser;
    parser.compile(expression_string, expression);

    for (x = T(-5.0); x <= T(+5.0); x += 0.001) {
        T y = expression.value();
        printf("%19.15f\t%19.15f\n", x, y);
    }
}



//Cpp file
void add_variable_(symbol_table_t st, char *varname, double *value) {
    const std::string varname_ = varname;
    bool r = st.add_variable(varname_, *value);
    printf("%d\n", r);
    r = st.add_constants();
}

void register_symbol_table_(expression_t ex, symbol_table_t st) {
    ex.register_symbol_table(st);
}
void compile_(parser_t parser,char *expression_string, expression_t ex) {
    const std::string expression_string_ = expression_string;
    parser.compile(expression_string_, ex);
}

double evaluate_(expression_t ex) {
    double val = ex.value();
    return (val);
}

int main() {
    trig_function<double>();

    double x;
    //exprtk::symbol_table<double> symbol_table;
    symbol_table_t symbol_table;
    add_variable_(symbol_table, "x", &x);
    symbol_table.add_constants();

    //exprtk::expression<double> expression;
    expression_t expression;
    register_symbol_table_(expression, symbol_table);

    //exprtk::parser<double> parser;
    parser_t parser;
    compile_(parser, "clamp(-1.0,sin(2 * pi * x) + cos(x / 2 * pi),+1.0)", expression);

    double q = -5.0, y = 0.0;
    for (x = q; x <= +5.0; x += 0.001) {
        y = evaluate_(expression);
        printf("%19.15f\t%19.15f\n", x, y);
    }
    return (0);
}

2 个解决方案

#1


10  

Definitely learn C++.

绝对学习C ++。

You could hide the templates in a cpp file and expose an interface to use them:

您可以在cpp文件中隐藏模板并公开接口以使用它们:

//Header
#ifdef __cplusplus
extern "C" {
#endif
  void push(int elt);
  int pop();
#ifdef __cplusplus
}
#endif

//Cpp file
static std::deque<int> queue;

void push(int elt) {
  queue.push_back(elt);
}

int pop() {
  auto tmp = queue.front();
  queue.pop_front();
  return tmp;
}

You can't instantiate a template via C, but you can use a header file that takes advantage of templates behind the scenes and link everything together. That said, I strongly recommend leaving C in the past, and learning C++; it grants more power, speed, and safety.

您无法通过C实例化模板,但您可以使用头文件,该文件利用幕后模板并将所有内容链接在一起。也就是说,我强烈建议过去离开C,学习C ++;它可以提供更多的动力,速度和安全性。

#2


0  

No.

C does not support templates, so no C interface can be available.

C不支持模板,因此没有C接口可用。

#1


10  

Definitely learn C++.

绝对学习C ++。

You could hide the templates in a cpp file and expose an interface to use them:

您可以在cpp文件中隐藏模板并公开接口以使用它们:

//Header
#ifdef __cplusplus
extern "C" {
#endif
  void push(int elt);
  int pop();
#ifdef __cplusplus
}
#endif

//Cpp file
static std::deque<int> queue;

void push(int elt) {
  queue.push_back(elt);
}

int pop() {
  auto tmp = queue.front();
  queue.pop_front();
  return tmp;
}

You can't instantiate a template via C, but you can use a header file that takes advantage of templates behind the scenes and link everything together. That said, I strongly recommend leaving C in the past, and learning C++; it grants more power, speed, and safety.

您无法通过C实例化模板,但您可以使用头文件,该文件利用幕后模板并将所有内容链接在一起。也就是说,我强烈建议过去离开C,学习C ++;它可以提供更多的动力,速度和安全性。

#2


0  

No.

C does not support templates, so no C interface can be available.

C不支持模板,因此没有C接口可用。