3

我正在尝试编写一个 C# 库来操作我的 C/C++ 头文件。我希望能够读取和解析头文件并在 C# 中操作函数原型和数据结构。由于#ifdefs 和类似的东西引起的所有代码分支,我试图避免编写C Parser。

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

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

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

4

2 回答 2

4

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

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

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

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

一个更通用的工具是我们的DMS Software Reengineering Toolkit,它带有C 前端;还有一个C++ 前端(是的,它们是不同的;C 和 C++ 绝对不是同一种语言)。这些处理各种 C 方言(正确配置时包括 MS 和 GCC),进行宏/条件扩展,构建 AST 和符号表(名称和类型解析是否正确)。

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

于 2012-05-11T15:38:37.700 回答
0

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

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

例子

  • 宏中带有##的任何东西

或者

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

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

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

等等等等

因此,标头解析和转换大多仅适用于半自动化使用(通过它手动运行清理的标头)或相当干净和一致的标头(例如较旧的 MS SDK 标头)

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

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

于 2012-05-11T15:06:28.843 回答