首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用std::string调用C++11中的函数

使用std::string调用C++11中的函数
EN

Stack Overflow用户
提问于 2022-10-01 02:55:37
回答 1查看 202关注 0票数 0

我想使用字符串值来调用函数。这个是可能的吗?有人能给我看看具体的实现吗。我会很感激的。

代码语言:javascript
复制
class obj {
    int num1;
    int num2;
}

int func1(obj o) {
   return o.num1 + o.num2;
}

// This is an example data set. This map would be populated with values in the map below with some piece of code.
std::map<std::string, std::string> funcNameMap = {{"func1", "func1"}};

int someFunction(std::string funcName, obj o) {
    // Get the value associated with the string "funcName" i.e. "func1". 
    // Calls function "func1" with value "o" and returns the value.
}

int main(){
   obj o;
   o.num1 = 1;
   o.num2 = 2;
   auto x = someFunciton("func1", o);
   std::cout << x << std::endl;
   return 0;
}

我正在编写一个收集公制数据的程序。我想为特定的度量执行一个特定的函数。我会将所有函数命名为与度量名称相同的函数,以便当我将度量名称命名为输入(string)时,它将执行特定的函数。我不希望if-else用于基于度量名称输入执行函数,因为我的程序正在收集100多个度量。如果-否则的话,这看起来会很尴尬。这就是为什么我要这样做的原因。

想要同时适用于操作系统窗口/linux的东西

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-10-01 03:54:33

一个解决方案是创建从函数名到函数本身的映射。我们知道函数是C/C++中的指针,所以在确定函数指针的类型之后,我们可以很容易地做到这一点。在您的示例中,目标函数类型是int (*)(obj)

代码片段:

代码语言:javascript
复制
#include <iostream>
#include <map>
#include <string>

class obj {
  public:
    int num1;
    int num2;
};

int func1(obj o) {  // type: int (*)(obj)
    return o.num1 + o.num2;
}

// create the mapping from name to function
std::map<std::string, int (*)(obj)> funcNameMap = {{"func1", func1}};

int someFunction(std::string funcName, obj o) {
    // Get the value associated with the string "funcName" i.e. "func1". 
    // Calls function "func1" with value "o" and returns the value.
    auto fn = funcNameMap.at(funcName);
    return fn(o);
}

int main(){
   obj o;
   o.num1 = 1;
   o.num2 = 2;
   auto x = someFunction("func1", o);
   std::cout << x << std::endl;
   return 0;
}

编辑:根据注释更新,使用动态共享库避免手动创建映射。我想你是在使用Linux。

首先,将类定义和目标函数的类型移到单独的头obj.hpp中。

代码语言:javascript
复制
class obj {               
  public:                 
    int num1;             
    int num2;             
};                        
// type of target functions
typedef int (*ftype)(obj);

将目标函数收集到一个分离的文件functions.cpp中,以构建动态共享库。

代码语言:javascript
复制
#include "obj.hpp"

extern "C"
int func1(obj o) {
    return o.num1 + o.num2;
}
extern "C"
int func2(obj o) {
    return o.num1 - o.num2;
}

在第三个文件main.cpp中,我们根据函数名从库中检索函数。

代码语言:javascript
复制
#include <iostream>
#include <map>
#include <dlfcn.h>
#include <cassert>
#include "obj.hpp"

// name mapping: public name to inner name
std::map<std::string, std::string> funcNameMap = {{"add", "func1"}, {"sub", "func2"}};

int retrieve_fn(void *dl_handler, std::string funcName, obj o) {
    assert(dl_handler != NULL && funcNameMap.count(funcName) != 0);
    auto real_fn_name = funcNameMap[funcName];
    auto fn = (ftype)dlsym(dl_handler, real_fn_name.c_str());
    auto dl_err = dlerror();
    if (dl_err) {
        std::cerr << "Load failed: " << dl_err << std::endl;
        return -999;
    }
    return fn(o);
}

int main(){
    obj o;
    o.num1 = 1;
    o.num2 = 2;
    // open dynamic shared library
    auto dl_name = "./functions.so";
    auto dl_handler = dlopen(dl_name, RTLD_LAZY);
    auto dl_err = dlerror();
    if (dl_err) {
        std::cerr << "Open failed: " << dl_err << std::endl;
        return -1;
    }
    auto x = retrieve_fn(dl_handler, "add", o);
    std::cout << x << std::endl;
    x = retrieve_fn(dl_handler, "sub", o);
    std::cout << x << std::endl;
    dlclose(dl_handler);
    return 0;
}

functions.cpp.构建动态共享库的

代码语言:javascript
复制
$ g++ functions.cpp -shared -fPIC -o functions.so

main.cpp.构建可执行文件的

代码语言:javascript
复制
$ g++ main.cpp -ldl -o main

  1. 运行并检查结果.

代码语言:javascript
复制
$ ./main
3
-1
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73915510

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档