听起来很奇怪,我需要在C ++中调用一个函数,我不知道签名。基本上,我想让用户指定参数列表和参数类型,然后尝试使用这些参数调用给定的函数。然后我想知道函数调用是否有效,如果它(奇迹般地)做了,返回值是什么(假设返回类型不是空的)。有没有办法实现这一目标?感谢。
答案 0 :(得分:5)
让您的函数获取变体数据类型列表,例如std::vector<boost::any>
让他们返回bool
表示成功或在失败时抛出异常。
如果您可以在编译时注册公开的函数,则甚至不必对您的函数进行限制,而是可以为必要的转换生成粘合代码。
答案 1 :(得分:3)
当然你可以在运行时这样做。例如,Gdb就是这样做的。但它需要大量的工作和对目标环境的理解。我怀疑可能有更好的方法来做你想做的事。
答案 2 :(得分:0)
这听起来并不太奇怪,但你仍然不能用C ++来做。在编译时检查C ++函数的签名。您可以做的最好的事情是将包含函数参数的向量或类似容器传递给函数。即使这样,在编译时也必须知道类型(或者至少是基类型,如果你使用继承)。
答案 3 :(得分:0)
如果您在运行时可以访问C ++编译器,则可以将假定的调用写入文件,编译它,然后将其作为DLL动态链接并尝试运行它。如果参数类型错误,或者该函数不存在,则DLL运行时链接失败;否则函数被调用,你得到返回值。
答案 4 :(得分:0)
好吧,如果你对mechanisim很灵活,你可以使用动态调度来做这件事。
你要做的是创建一个抽象基类,它有一个“run it”方法返回一个返回值。然后你有一个引擎,它保存了一个指向这个(抽象)基类对象的指针列表,客户可以通过某种注册调用来提供给你。
客户编写他们自己的“运行它”实现,可以做任何他们需要做的事情,只要他们在完成后正确填写引擎的返回值。他们的“自定义参数”是作为类的版本的额外成员实现的,可以在构造对象时填写,也可以通过单独的调用填充。
这为您提供了调用例程,运行它并检查结果所需的内容,而无需知道它们的自定义参数是什么,或者确切地知道它们的例程。
答案 5 :(得分:0)
这是一个荒谬的问题,因为如果用户(从c-code 调用)在编译时不知道参数的类型,他将不能提供正确类型的参数,即使可以构造动态类型的函数指针。
即使在另一个答案中表达的gdb
示例也假设用户在调用时具有适当和已知类型的变量。
由于这是真的,我推断用户确实知道参数的正确类型,然后这就成了如何在编译时创建一个带有一组已知类型参数的函数的问题。
这很简单:如果用户有一个int
和两个float
,并希望获得int
作为回报,并希望调用假设的函数{{1}因此,其类型必须为swizzle
,然后只需声明此类型的指针,使用int (IIIF*)(int, int, float)
获取函数ldload
,然后调用它。
但是,有一些特殊情况,例如,如果所有参数都是指针,则可以实现。
请注意,在编译时已知包括模板等情况,其值在编译时从推断在点和模板实例化时从显式或隐式类型信息中推断出来。
答案 6 :(得分:0)
如何在c ++ ox中使用rvalue引用?
template<typename Function>
void FunCall( Function&& f)
{
f();
}
void Fun_Int(int x)
{
using std::cout;
using std::endl;
cout << "I''m Fun_Int with " << x << endl;
}
void Fun_Str(const string& str1)
{
using std::cout;
using std::endl;
cout << "I'm Fun_Str with " << str1 << endl;
}
void RvaluesDemo()
{
for (int i = 0; i < 5; i++)
{
FunCall([&]
{
Fun_Int(i);
});
}
string str = "ABCDEF";
for (int i = 0; i < str.size(); i++)
{
ostringstream os;
os << str[i];
FunCall([&]
{
Fun_Str(os.str());
});
}
}
答案 7 :(得分:0)
有一个名为“ libffi”的C库,可让您调用带有未知参数的函数并在编译时返回类型。
很难知道呼叫是否成功,因为我们的级别太低,计算机本质上认为您正在做的事情是正确的,如果不正确,则可能发生任何事情。有时它会成功,但会给您带来垃圾,有时可能会崩溃,有时可能会出现实际错误。
答案 8 :(得分:-1)
这听起来像是在应用中包含动态类型脚本语言的保姆。嵌入像Lua或Python这样的东西,使你想要可调用的函数可用于脚本语言。或者,如果您正在尝试实现这样的事情,请查看Boost :: Python,了解如何实现它的先例。