如何在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的答案,我认为我需要创建一个函数注册表。我想它应该作为一个指向函数的指针数组。这是问题,如何声明函数指针数组?
答案 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)
有两种方法可以做到这一点:
动态加载
GetModuleFileName()
hModule = NULL
这给出了可执行文件的路径。
使用LoadLibrary(Executable_Name)
将自身加载到内存中。dloopen()
与NULL
一起使用,并将其自身加载到内存中。在Windows和Linux中,您都可以定义void* (function*)()
指针。这始终适用于没有参数的所有签名。这不适用于类方法。
使用命名空间系统
这个命名空间很容易,您可以使用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编程语言之间的无缝互操作。”