在运行时将.h头文件解析为c#数据结构

时间:2012-05-11 08:39:39

标签: c# c++ parsing compiler-construction compilation

我正在尝试编写一个C#库来操作我的C / C ++头文件。我希望能够读取和解析头文件并在C#中操作函数原型和数据结构。我正在努力避免编写C解析器,因为#ifdefs引起的所有代码都是这样的。

我尝试过使用EnvDTE,但找不到任何体面的文档。 任何想法我该怎么做?

编辑 - 谢谢你的答案......这里有一些关于我的项目的更多细节:我正在使用调试API编写一个类似ptrace的Windows工具,这使我能够跟踪已编译的二进制文件并查看调用哪些Windows API 。我还想看看每个调用中给出了哪个参数以及给出了什么返回值,所以我需要知道API的定义。我也想知道我自己的库的定义(因此,头解析方法)。我想到了3个解决方案: *解析头文件 *解析PDB文件(我使用DIA SDK编写了一个原型,但不幸的是,符号PDB只包含有关API的一般信息,而不包含带参数和返回值的真实原型) *爬过MSDN在线图书馆(自动或手动)

有没有更好的方法在c#中运行时获取Windows API和我的库的名称和类型?

2 个答案:

答案 0 :(得分:4)

解析C(甚至“只是”标题)很难;语言比人们记得的复杂得多, 然后是预处理器,最后是解析器的问题。 C ++基本上包含了所有的C,而C ++ 11在这里问题更严重。

人们通常可以针对一组有限的输入破解98%的解决方案,通常使用Perl中的正则表达式或其他一些字符串hackery。如果这对你有用,那很好。通常情况下,2%导致被黑客攻击的解析器窒息或产生错误的答案,然后您可以调试结果并手动攻击98%的解决方案输出。

黑客攻击解决方案往往在真正的头文件上失败,这似乎集中了宏和条件中的怪异(有时甚至在条件臂中混合不同的C和C ++方言)。以典型的Microsoft .h文件为例。这似乎是OP想要处理的内容。预处理消除了部分问题,现在您将遇到C和/或C ++的真正复杂性。即使使用预处理,您也无法获得98%的真实头文件解决方案;你需要typedef,因此也需要名称和类型解析。你可以“解析”FOO X;这告诉你X是FOO类型的...... oops,那是什么?只有符号表才能确定。

GCCXML为C的GCC方言做了所有这些预处理,解析和符号表构造....微软的方言是不同的,我不认为GCCXML可以处理它。

更通用的工具是我们的DMS Software Reengineering Toolkit,其 C front end;还有一个C++ front end(是的,它们是不同的; C和C ++远远不是同一种语言)。这些处理各种各样的C方言(正确配置时为MS和GCC),进行宏/条件扩展,构建AST和符号表(正确地命名和键入分辨率)。

您可以通过抓取生成的符号表结构来添加自定义以提取所需的信息。您必须将您想要的内容导出到C#(例如,生成您的C#类),因为DMS不是用.net语言实现的。

答案 1 :(得分:0)

在最常见的情况下,头文件只能使用,不能转换。

这可能是因为预处理器(#define)使用宏,结构常量的片段等只能在上下文中使用时才有意义。

实施例

  • 宏中带##的任何内容

//header
#define mystructconstant "bla","bla"

// in using .c
char test[10][2] ={mystructconstant};

但你不能简单地丢弃所有的宏,因为那样你就不会处理非常常见的调用约定宏了

等等。

因此,标头解析和转换主要仅适用于半自动使用(通过它手动运行已清理的标头)或合理清晰且一致的标头(例如较旧的MS SDK标头)

由于一般情况如此困难,因此没有太多可用的。每个人都为自己的标题制作快速而肮脏的东西。

我所知道的唯一更通用的工具是SWIG。