C ++中的动态源代码

时间:2009-05-21 20:51:29

标签: c++ dynamic evaluation

如何在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的答案,我认为我需要创建一个函数注册表。我想它应该作为一个指向函数的指针数组。这是问题,如何声明函数指针数组?

14 个答案:

答案 0 :(得分:17)

你问题的真正答案是:

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

答案 1 :(得分:16)

C ++是一种编译语言,因此,没有相当于“eval()”。

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

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

答案 2 :(得分:7)

如果你真的需要,你可以embed a C/C++ interpreter加入你的程序。但是,您也可以embed a more script-like language代替。

答案 3 :(得分:4)

要回答关于如何做到这一点的问题,答案是:它不是。

必须使用像eval()这样的东西通常是一个设计问题。如果你确实需要它,可以嵌入一个脚本语言,比如Lua或Python。

答案 4 :(得分:4)

如果你把函数1 ..函数放在一个DLL中,你可以简单地将它们拉出来并使用dlopen / dlsym按名称调用它们,这可能会让你获得90%的目标。

答案 5 :(得分:4)

函数指针怎么样?

答案 6 :(得分:2)

C ++语言本身无法直接执行此操作。但是您可以根据用户输入(或其他)使用平台特定函数来调用给定DLL中的任何函数。例如,在Windows上,查找GetProcAddress()和LoadLibrary()

答案 7 :(得分:2)

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

答案 8 :(得分:2)

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

  1. 动态加载

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

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

  2. 使用命名空间系统

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

答案 9 :(得分:1)

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

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

答案 10 :(得分:1)

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

答案 11 :(得分:1)

  

如何声明函数指针数组?

C程序员对此问题的回答:

使用cdecl。

  

的cdecl&GT;声明functable作为指针   function(int,指向int的指针)   返回双

     

双   (* functable)(int,int *)

     

的cdecl&GT;声明functable作为指向函数(int)的指针的数组17返回double

     

double(* functable [17])(int)

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

如果您使用的是C ++,则可能有助于使用std :: map&lt; YourFunctionPointerType &gt;而不是数组,因为你想要映射字符串......

OO方法:

使用多态。它并没有立即解决你的问题,但如果你这样做,很有可能为每个函数都有一个类。

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

答案 12 :(得分:0)

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

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

另请注意,出于安全考虑,eval()几乎绝不是您希望以任何语言使用的内容。

答案 13 :(得分:0)

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