从 DLL 导出的函数中的 RTTI
我有一个 Visual Studio 2008 C++ dll,我想在其中接受可变数量的参数并知道每个参数的类型。例如:
__declspec( dllexport ) void Foo( const char* object, const char* function, ... )
{
printf( "%s::%s( ", object, function );
va_list list;
va_start( list, function );
while( va_arg( list, ??? ) )
{
printf( "[%s] %s ", type, value );
}
va_end( list );
printf( " )\r\n" );
}
预期的用法是这样的:
Buzz api;
int a = 1;
api.DoSomething( a, "hello", 0.2f );
Foo( "Buzz", "DoSomething", a, "hello", 0.2f );
预期的输出将如下所示:
Buzz::DoSomething( [int] 1, [const char*] "hello", [float] 0.2 )
这是或类似的东西,可以使用 RTTI 吗?如果可变参数解决方案不可能(我怀疑它不可能),那么我可以接受包含 1-n 参数的多个重载的解决方案。
谢谢, 保罗·H
I have a Visual Studio 2008 C++ dll where I would like to accept a variable number of arguments and know the type of each one. For example:
__declspec( dllexport ) void Foo( const char* object, const char* function, ... )
{
printf( "%s::%s( ", object, function );
va_list list;
va_start( list, function );
while( va_arg( list, ??? ) )
{
printf( "[%s] %s ", type, value );
}
va_end( list );
printf( " )\r\n" );
}
The expected usage is something like this:
Buzz api;
int a = 1;
api.DoSomething( a, "hello", 0.2f );
Foo( "Buzz", "DoSomething", a, "hello", 0.2f );
Where the expected output would look like this:
Buzz::DoSomething( [int] 1, [const char*] "hello", [float] 0.2 )
Is this, or something like it, possible with RTTI? If a variadic argument solution is not possible (and I suspect it is not), I'm okay with one that includes multiple overloads for 1-n arguments.
Thanks,
PaulH
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
第一:C++ 支持“C”样式的可变参数函数,仅与 C 代码兼容。不建议您在新的 C++ 代码中使用它们,因为它们无法强制类型安全。
可变参数函数将其所有“...”参数作为堆栈上的无类型值传递,您作为参数传递的值的类型必须由您(作为该函数的作者)的逻辑推导出来)放入您编写的函数中。也就是说,唯一告诉 printf 参数类型(格式字符串后面的参数)的是格式字符串本身。
这在 C++ 中和在 C 中一样正确。RTTI 无法为堆栈上的任意值提供任何类型信息。
如果这些值都是指向类层次结构中的对象(相关类的实例)的指针,那么您可以使用dynamic_cast来确定类型...但是您必须自己编写代码来处理不同的类,该语言不会为你做那件事。
First: "C" style variadic functions are supported in C++ for compatibility with C code only. It is not recommended that you should use them in new C++ code as they cannot enforce type safety.
A variadic function passes all of its "..." arguments as untyped values on the stack, The types of the values you pass as parameters must be deduced by the logic that you (as author of that function) put into the function you write. That is, the only thing that tells printf the types of the parameters (those that follow the format string) is the format string itself.
This is as true in C++ as it is in C. There is no way for RTTI to provide any type information for arbitrary values on the stack.
If the values were all pointers to objects (instances of related classes) within a class hierarchy then you could use a dynamic_cast to determine the types ... but you'd have to write code to handle the different classes yourself, the language would not do that for you.
可变参数解决方案是可能的,但不是 C 方式,也不是该语言的当前版本。如果您的编译器实现了可变参数模板,您可以使用它们来实现。您可以通过使用具有一长串默认参数的函数来模拟当前版本的可变参数模板,最高可达某个任意最大值(如果使用预处理器魔法,则由变量设置)。
因此,根据您想要采取的方式,您需要学习可变参数模板和/或预处理器。一旦您进行了必要的研究,前者就会变得显而易见。后者有点困难,但是如果你查看 boost::function 等内容的 src,它就会变得很明显。
A variadic argument solution is possible, but not the C way and not in the current version of the language. If your compiler implements variadic templates though, you could do it with them. You can mimic variadic templates with current version up to some arbitrary maximum (set by a variable if you use preprocessor magic) by having a function with a long list of default arguments.
So, depending on which way you want to go you need to learn variadic templates and/or the preprocessor. The former will become obvious once you do the research necessary. The latter is a bit tougher, but if you look at the src to things like boost::function it will become apparent.