4

如何在 C++ 中处理动态源代码?是否可以使用类似 eval("foo") 的东西?

我有一些函数需要根据用户的选择来调用:

     void function1 ();
     void function2 ();
     ...
     void functionN ();

     int main (int argv, char * argv [])
     {
         char * myString = new char [100];
         ...
         myString = "1" //user input            
         cout << eval("function"+myString)();
     }

通常是怎么做的?

UPD:根据 slacy 和 clinisbut 的回答,我认为我需要创建一个函数注册表。我想它应该作为一个指向函数的指针数组。问题来了,如何声明一个指向函数的指针数组?

4

14 回答 14

16

你的问题的真正答案是这样的:

extern "C" {
void function1 ();
void function2 ();
void function3 ();
}


 int main (int argv, char * argv [])
 {
     char * myString = new char [100];
     ...
     myString = "function1"; //user input     

     void (*f)() = dlsym(RTLD_NEXT, myString);
     f();
 }

您可以获得二进制文件中定义的函数(通过它的名称,如果它是用 extern "C" 声明的),然后调用它。

在 Windows 上,它变得更丑陋,但仍然可能 - 阅读 GetProcAddress

于 2009-05-21T21:14:47.617 回答
15

C++ 是一种编译语言,因此不存在“eval()”等价物。

对于您提到的特定示例,您可以创建一个函数注册表,将输入(字符串)映射到输出(函数指针),然后调用结果函数。

有几个可用的 C++ 解释器库,虽然性能会很差,但它们可能会完成你想要的。谷歌搜索“C++ 解释器”。我已经看到了“ Ch ”、“ CINT ”和“clipp”的结果

于 2009-05-21T20:52:17.070 回答
7

如果你真的需要这个,你可以在你的程序中嵌入一个 C/C++ 解释器。但是,您也可以嵌入更类似于脚本的语言

于 2009-05-21T20:54:20.653 回答
4

要回答您通常如何做到这一点的问题,答案是:不是。

必须使用类似的东西eval()通常是一个设计问题。如果您确实需要它,请嵌入脚本语言,例如 Lua 或 Python。

于 2009-05-21T21:00:04.823 回答
4

如果您将 function1 .. functionN 放入 DLL 中,您可以简单地将它们拉出并使用 dlopen/dlsym 按名称调用它们,这可能会为您提供 90% 的方法。

于 2009-05-21T21:01:50.717 回答
4

函数指针呢?

于 2009-05-22T09:18:47.367 回答
2

C++ 语言本身不能直接做到这一点。但是您可以根据用户输入(或其他)使用特定于平台的函数来调用给定 DLL 中的任何函数。例如,在 Windows 上,查找 GetProcAddress() 和 LoadLibrary()

于 2009-05-21T21:03:12.477 回答
2

这是嵌入解释语言(如 LUA)的一个很好的例子。如果您创建与 C++ API 的 LUA 绑定,您将能够通过应用程序中的 LUA 代码动态执行您的代码。

于 2009-05-21T21:19:28.933 回答
2

有两种方法可以做到这一点:

  1. 动态加载

    • Windows:这给出了可执行文件的路径GetModuleFileName()hModule = NULL用于LoadLibrary(Executable_Name)将自身加载到内存中。
    • Linux:使用dloopen()withNULL并将其自身加载到内存中。

    在 Windows 和 Linux 中,您都可以定义一个void* (function*)()指针。这始终适用于所有没有参数的签名。这不适用于类方法。

  2. 使用命名空间系统

    这个命名空间很容易,您可以使用Inspect功能和InvokeMember方法来动态调用类方法并从类内部访问变量。

于 2011-11-27T23:37:00.940 回答
1

你不能在 C++ 中做到这一点。它是一种强制编译的语言。

无论如何,实现 eval() 所需的许多信息都会在运行时丢失。

于 2009-05-21T20:52:33.077 回答
1

我将构建一个函数指针数组或 STL 列表,以及您找到的触发对它们的调用的字符串。如果你真的需要调用任意函数,你应该调查 RTTI http://en.wikipedia.org/wiki/Run-time_type_information

于 2009-05-21T21:00:08.130 回答
1

如何声明一个指向函数的指针数组?

C程序员对这个问题的回答:

使用 cdecl。

cdecl> 将 functable 声明为指向函数的指针 (int,pointer to int) 返回双精度

双 (*functable)(int , int *)

cdecl> 将 functable 声明为返回 double 的函数 (int) 指针的数组 17

双 (*functable[17])(int)

请注意,函数会自动转换为指向函数的指针,就像数组衰减为指针一样。您不需要 & 来获取函数的地址以将其放入指针中。

如果您使用 C++,则使用 std::map< YourFunctionPointerType > 而不是数组可能会有所帮助,因为无论如何您都想映射字符串...

OO方法:

改用多态性。它不会立即解决您的问题,但是如果您这样做,则很有可能为每个函数设置一个类。

请注意,从根本上说,vtable 是一个指向函数的指针表。

于 2009-05-30T00:49:44.460 回答
0

你想要的是反射。C++ 默认不支持它,但是很多人已经为各种目的编写了全面的反射系统。我想到的一个是将 C++ 函数绑定到自定义脚本语言。

其他人提到使用 switch 语句(或更准确地说是 if/else 树)。这与可能出现的反射系统一样简单……它可能是您项目的最佳解决方案。C++ 中的反射是一种相当先进的技术,通常需要大量额外的代码……有时甚至需要自定义预处理器。

另请注意,出于安全目的, eval() 几乎绝不是您想在任何语言中使用的东西。

于 2009-05-22T09:31:32.737 回答
0

在 C++ 应用程序中嵌入和评估代码的最佳方式可能是使用像 python 这样的脚本语言。使用Boost.Python,“一个 C++ 库,可实现 C++ 和 Python 编程语言之间的无缝互操作性。”

于 2011-03-09T05:43:54.467 回答