检索头文件中定义的结构列表
retrieve a list of structs defined in a header file
我想检索头文件中所有结构的列表,例如CommCtrl.h:
中的结构选择
LVCOLUMNW,LVITEMW,REBARINFO,TVITEMW
这与从结构列表开始并检索其 sizeof 值的更广泛目标相关:
[STRUCT=sizeof64:sizeof32]
LVCOLUMNW=56:44
LVITEMW=88:60
REBARINFO=16:12
TVITEMW=56:40
目前我将 cpp 文件编译为 x64/x32 exe 以确定头文件是否包含结构(失败时返回空白),并确定结构的 sizeof 值:
#define UNICODE 1
#include <iostream>
#include <Windows.h>
int main()
{
std::cout << sizeof(BITMAPINFOHEADER) << std::endl;
return 0;
}
如果我可以动态地引用结构名称,或者忽略无效的结构名称,那么我可以更有效地做到这一点。
最终我想将上面的代码应用到这个 19486 的列表中 'Win words':
http://katahiromz.web.fc2.com/win32/winwords.txt
另一个想法是检索 Visual Studio 项目中所有当前定义的结构名称的列表,如果可能的话。
这里是一些临时代码,用于通过 AHK 列出头文件(.h 文件)中的结构,然后通过 C++ 检索它们的大小。生成的列表不能保证 100% 完整,但脚本已证明在检索结构名称方面非常有效。在 CommCtrl.h 和 WinUser.h.
上测试
;AHK v2 script
#Warn
ListLines("Off")
;q:: ;list structs in a header file (.h file) (provisional script)
vPath := "C:\Program Files (x86)\Windows Kits.1\Include\um\CommCtrl.h"
;vPath := "C:\Program Files (x86)\Windows Kits.1\Include\um\WinUser.h"
if !FileExist(vPath)
{
MsgBox("error: file not found:`r`n" vPath)
return
}
vText := FileRead(vPath)
vDoGetNext := 0
vTemp2 := ""
vIndent := ""
VarSetCapacity(vOutput, 1000000*2)
VarSetCapacity(vListDefine, 1000000*2)
oDict := ComObjCreate("Scripting.Dictionary")
;get struct names from 'typedef struct' definitions
;and store potential struct names from '#define' directives
Loop Parse vText, "`n", "`r"
{
vTemp := LTrim(A_LoopField) ;remove leading spaces/tabs
vTemp := RegExReplace(vTemp, "[ `t]+", " ")
vTemp := RegExReplace(vTemp, " //.*")
if (SubStr(vTemp, 1, 7) = "#define")
{
;ignore numeric definitions etc
if !RegExMatch(vTemp, "[(\\-:" Chr(34) "]| \d")
vListDefine .= vTemp "`r`n"
continue
}
vTemp := A_LoopField
;if (vPos := RegExMatch(vTemp, "typedef"))
if (vPos := RegExMatch(vTemp, "typedef struct"))
{
vTemp2 := vTemp
vIndent := SubStr(vTemp, 1, vPos-1)
vDoGetNext := 1
}
else if vDoGetNext
&& (SubStr(vTemp, 1, StrLen(vIndent)+1) = vIndent "}")
{
vTemp := RegExReplace(vTemp, "^[} ]+|[,;].*")
if !(vTemp = "")
&& !oDict.Exists("" vTemp)
&& !(vTemp = "DUMMYUNIONNAME")
{
oDict.Item["" vTemp] := 1
vOutput .= vTemp "`r`n"
;vOutput .= vTemp2 "`t" vTemp "`r`n"
}
vDoGetNext := 0
}
}
;get struct names from stored '#define' directives
;lines of the form '#define newname oldname'
vOutput .= "`r`n"
Loop Parse vListDefine, "`n", "`r"
{
oTemp := StrSplit(A_LoopField, " ")
if (oTemp.Length() = 3)
&& !oDict.Exists("" oTemp.2) ;new name not seen before
&& oDict.Exists("" oTemp.3) ;old name seen before
{
oDict.Item["" oTemp.2] := 1
vOutput .= oTemp.2 "`r`n"
}
}
;get raw list of structs:
;Clipboard := RTrim(vOutput, "`r`n") "`r`n"
;MsgBox(vOutput)
vList := vOutput
VarSetCapacity(vOutput, StrLen(vList)*10*2)
Loop Parse vList, "`n", "`r"
{
vTemp := A_LoopField
if (vTemp = "")
{
vOutput .= "`r`n"
continue
}
vOutput .= "std::cout << " Chr(34) vTemp "=" Chr(34) " << sizeof(" vTemp ") << std::endl;`r`n"
}
Clipboard := RTrim(vOutput, "`r`n") "`r`n"
oDict := ""
MsgBox("done")
return
示例 C++ 代码使用 AHK 脚本生成的代码。
//structs get sizes
#include "stdafx.h"
#include <iostream>
#include "Windows.h"
#include "CommCtrl.h"
int _tmain(int argc, _TCHAR* argv[])
{
std::cout << "TVITEMA=" << sizeof(TVITEMA) << std::endl;
std::cout << "TVITEMW=" << sizeof(TVITEMW) << std::endl;
std::cout << "TVITEM=" << sizeof(TVITEM) << std::endl;
std::getchar();
return 0;
}
注意:另一种方法是从头文件中检索唯一的字符串,将它们粘贴到Visual Studio中,等待Visual Studio为适当的单词着色,将列表复制到写字板,另存为一个 rtf 文件,并为彩色单词解析原始 rtf。
也在这里发布:
C++: list structs in a header file - AutoHotkey Community
我想检索头文件中所有结构的列表,例如CommCtrl.h:
中的结构选择LVCOLUMNW,LVITEMW,REBARINFO,TVITEMW
这与从结构列表开始并检索其 sizeof 值的更广泛目标相关:
[STRUCT=sizeof64:sizeof32]
LVCOLUMNW=56:44
LVITEMW=88:60
REBARINFO=16:12
TVITEMW=56:40
目前我将 cpp 文件编译为 x64/x32 exe 以确定头文件是否包含结构(失败时返回空白),并确定结构的 sizeof 值:
#define UNICODE 1
#include <iostream>
#include <Windows.h>
int main()
{
std::cout << sizeof(BITMAPINFOHEADER) << std::endl;
return 0;
}
如果我可以动态地引用结构名称,或者忽略无效的结构名称,那么我可以更有效地做到这一点。
最终我想将上面的代码应用到这个 19486 的列表中 'Win words': http://katahiromz.web.fc2.com/win32/winwords.txt
另一个想法是检索 Visual Studio 项目中所有当前定义的结构名称的列表,如果可能的话。
这里是一些临时代码,用于通过 AHK 列出头文件(.h 文件)中的结构,然后通过 C++ 检索它们的大小。生成的列表不能保证 100% 完整,但脚本已证明在检索结构名称方面非常有效。在 CommCtrl.h 和 WinUser.h.
上测试;AHK v2 script
#Warn
ListLines("Off")
;q:: ;list structs in a header file (.h file) (provisional script)
vPath := "C:\Program Files (x86)\Windows Kits.1\Include\um\CommCtrl.h"
;vPath := "C:\Program Files (x86)\Windows Kits.1\Include\um\WinUser.h"
if !FileExist(vPath)
{
MsgBox("error: file not found:`r`n" vPath)
return
}
vText := FileRead(vPath)
vDoGetNext := 0
vTemp2 := ""
vIndent := ""
VarSetCapacity(vOutput, 1000000*2)
VarSetCapacity(vListDefine, 1000000*2)
oDict := ComObjCreate("Scripting.Dictionary")
;get struct names from 'typedef struct' definitions
;and store potential struct names from '#define' directives
Loop Parse vText, "`n", "`r"
{
vTemp := LTrim(A_LoopField) ;remove leading spaces/tabs
vTemp := RegExReplace(vTemp, "[ `t]+", " ")
vTemp := RegExReplace(vTemp, " //.*")
if (SubStr(vTemp, 1, 7) = "#define")
{
;ignore numeric definitions etc
if !RegExMatch(vTemp, "[(\\-:" Chr(34) "]| \d")
vListDefine .= vTemp "`r`n"
continue
}
vTemp := A_LoopField
;if (vPos := RegExMatch(vTemp, "typedef"))
if (vPos := RegExMatch(vTemp, "typedef struct"))
{
vTemp2 := vTemp
vIndent := SubStr(vTemp, 1, vPos-1)
vDoGetNext := 1
}
else if vDoGetNext
&& (SubStr(vTemp, 1, StrLen(vIndent)+1) = vIndent "}")
{
vTemp := RegExReplace(vTemp, "^[} ]+|[,;].*")
if !(vTemp = "")
&& !oDict.Exists("" vTemp)
&& !(vTemp = "DUMMYUNIONNAME")
{
oDict.Item["" vTemp] := 1
vOutput .= vTemp "`r`n"
;vOutput .= vTemp2 "`t" vTemp "`r`n"
}
vDoGetNext := 0
}
}
;get struct names from stored '#define' directives
;lines of the form '#define newname oldname'
vOutput .= "`r`n"
Loop Parse vListDefine, "`n", "`r"
{
oTemp := StrSplit(A_LoopField, " ")
if (oTemp.Length() = 3)
&& !oDict.Exists("" oTemp.2) ;new name not seen before
&& oDict.Exists("" oTemp.3) ;old name seen before
{
oDict.Item["" oTemp.2] := 1
vOutput .= oTemp.2 "`r`n"
}
}
;get raw list of structs:
;Clipboard := RTrim(vOutput, "`r`n") "`r`n"
;MsgBox(vOutput)
vList := vOutput
VarSetCapacity(vOutput, StrLen(vList)*10*2)
Loop Parse vList, "`n", "`r"
{
vTemp := A_LoopField
if (vTemp = "")
{
vOutput .= "`r`n"
continue
}
vOutput .= "std::cout << " Chr(34) vTemp "=" Chr(34) " << sizeof(" vTemp ") << std::endl;`r`n"
}
Clipboard := RTrim(vOutput, "`r`n") "`r`n"
oDict := ""
MsgBox("done")
return
示例 C++ 代码使用 AHK 脚本生成的代码。
//structs get sizes
#include "stdafx.h"
#include <iostream>
#include "Windows.h"
#include "CommCtrl.h"
int _tmain(int argc, _TCHAR* argv[])
{
std::cout << "TVITEMA=" << sizeof(TVITEMA) << std::endl;
std::cout << "TVITEMW=" << sizeof(TVITEMW) << std::endl;
std::cout << "TVITEM=" << sizeof(TVITEM) << std::endl;
std::getchar();
return 0;
}
注意:另一种方法是从头文件中检索唯一的字符串,将它们粘贴到Visual Studio中,等待Visual Studio为适当的单词着色,将列表复制到写字板,另存为一个 rtf 文件,并为彩色单词解析原始 rtf。
也在这里发布:
C++: list structs in a header file - AutoHotkey Community