|
C At Work 专栏...
枚举声明,模板函数特化
原著:Paul DiLascia
翻译:NorthTibet
逆风者 下载源代码:CAtWork0507.exe (204KB)
原文出处:Enum
Declarations, Template Function Specialization
我读过了您2005年4月的文章:“Wrappers: Use Our ManWrap Library to Get the Best of
.NET in Native C Code”,文章中没有提供 DumpEnum 程序。请问从哪里能得到它?
Jarrad Waterloo
给定某个 .NET 框架类的名字,如 MenuItem 或窗体的名字,有没有办法知道是哪个程序集包含着该类?
Several Readers
我很乐意解释我是如何写就 DumpEnum
的,甚至给出代码。此间我还将回答第二个问题。不过首先让我为其他读者解释一下 DumpEnum
是做什么的。在四月发表的文章中,我要做的一件事情是写一个 C 枚举来完全充当 .NET 框架类型
RegexOptions。RegexOptions 是一个枚举类型,你可以用 Regex::Match 和 Replace
之类的方法来控制匹配。例如,你可以用 RegexOptions::IgnoreCase 来调用 Regex::Match 以忽略大小写,或者
RegexOptions::Singleline 来将输入串作为一行。RegexOptions 的值如
Figure 1 所示。
为了从本机C 代码传递 RegexOptions,你需要一个具有相同值的
C-式样枚举。如果你仅仅是一时之需,那么编写这样的代码最快的方法是从文档中将之拷贝到你的 C 文件,然后按照 C
的语法编辑它。但如果你要进行印刷,或修改选项,或者想要包装若干枚举类型的话,那么最好最可靠的方法是写一个工具,它能自动生成 C
代码——尤其反射使之更容易;.NET 框架提供了全部描述自身所需的信息。所以我写了一个小程序 DumpEnum,你可以从命令行运行它,像这样:DumpEnum RegexOptions
DumpEnum 将名字/值对写成 C/C 代码送到标准输出。你可以像下面这样将输出重定向到一个文件:
DumpEnum RegexOptions > regopt.h
然后将 regopt.h 插入到你的头文件。在我的文章中,RegexWrap.h 就是这么做的。DumpEnum 为
RegexOptions 实际生成的文件如
Figure 2 所示。
现在你知道 DumpEnum 是做什么的了,下面你会明白我是如何实现它的。
每一个框架类都是由 System.Type 类描述。它具备 Name 属性以获取类型名,IsEnum 告之该类型是否为枚举。DumpEnum
要做的第一件事情是不论什么类型名,都要获得 Type,把它们传递到命令行——例如,RegexOptions,实现它并不是想像的那么容易。获得
Type 最普通的两个方法是:如果已知对象实例,则调用 obj->GetType;否则用 __typeof。例如:
#using <System.dll>
using namespace System::Text::RegularExpressions;
...
Type *t = __typeof(RegexOptions);
在 C 中使用托管类型必须用 __typeof,因为 typeof 已经有定义(在新的 C \CLI 中要用 typeid<>)。但
__typeof 只能用于符号名,而不是字符串,这意味着编译时你得知道名字,以及哪个程序集和其所属的名字空间。DumpEnum
在编译时不具备这些信息,所以要从命令行参数中获得类型名。DumpEnum 也不具备对象实例,所以它无法调用 Object::GetType,怎么办呢?
还有另一个得到 Type 的方法。如果已知该类型属于哪个程序集,那么可以加载它并调用 Assembly::GetType,它有一个串参数。但 Assembly::GetType
需要完整的类型名,并且你得知道要加载哪个程序集。DumpEnum 给我的第一个痛是要我在命令行敲入下面这些信息: DumpEnum System.dll System.Text.RegularExpressions.RegexOptions
本文章更多内容:1 - 2 - 3 - 4 - 5 - 下一页>> |