Editplus配置VC++ 与/d1reportSingleClassLayout
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Editplus配置VC++ 与/d1reportSingleClassLayout相关的知识,希望对你有一定的参考价值。
前篇文章:Editplus配置VC++(1) 及相关注意事项
VC++有两个隐含编译选项/d1reportSingleClassLayout和/d1reportAllClassLayout /d1 reportSingleClassLayout和/d1 reportAllClassLayout或将/改为-都行
比如
cl.exe /d1reportSingleClassLayoutClassName //ClassName前面无空格 //或 cl.exe /d1reportAllClassLayout
但是,ClassName是类名的substring,任何匹配它的类名都会被输出。比如想看class A,你输入了/d1reportSingleClassLayoutA,但是你会发现会编译器输出很多无关的类,如struct ABC、Class inAttribute Class dbA...因为它们的类名都包含有A这个字母。
你可能说是不是因为#include了库的缘故,如#include<iostream>,把它去掉呢。。。试了,你会发现还不行。。。cl.exe有很多编译选项,如/X忽略标准include目录,但我一一试了,都没什么用。。。把下面批处理中的call "%VS120COMNTOOLS%vsvars32.bat"去了也不行(去掉该语句能加快启动速度,但不推荐,因为不包含库的话,若类包含有库中的类对象,cl.exe如何正确计算类的布局呢)
至于,/d1reportAllClassLayout相比/d1reportSingleClassLayout,无用的输出只多不少,因此这里不用它。。。
既然不行,就只能捕获标准输出,然后过滤掉了无用的信息了。依然在VC++目录建立个bat文件,内容如下:
@echo off call "%VS120COMNTOOLS%vsvars32.bat" if "%2" == "" goto error if "%1" == "" goto error cl.exe /nologo /w /Zs /d1reportSingleClassLayout%2 %1 goto :eof :error echo Error:参数错误 - 是否划定了类名? goto :eof
其实没什么,就是调用了下cl.exe而已。/Zs选项是只检查语法,不产生.obj .exe等文件了。。。
怎么捕获编译输出,这需要用到Windows里的匿名通道来重定向标准输出。这里我们编写个控制台程序clsLayout.exe,它会被EditPlus调用。而clsLayout.exe里会创建通道并创建子进程执行批处理。然后捕获批处理的标准输出,并过滤内容,只输出想要的。。。
这里直接贴代码了,如下,其中CMDLine函数是我在网上找的,直接拿来修改了
#include <iostream> ////#include <fstream> #include <string> #include <windows.h> using namespace std; char g_name[101] = {}; bool CMDLine(std::string cmd) { SECURITY_ATTRIBUTES sa; HANDLE hRead,hWrite; sa.nLength=sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor=NULL; sa.bInheritHandle=TRUE; if (!CreatePipe(&hRead,&hWrite,&sa,0)) { cout << "CreatePipe失败" << endl; return false; } STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si,sizeof(si)); ZeroMemory(&pi,sizeof(pi)); si.cb=sizeof(STARTUPINFO); GetStartupInfo(&si); si.hStdError=hWrite; si.hStdOutput=hWrite; si.wShowWindow=SW_HIDE; si.dwFlags=STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; if (!CreateProcess(NULL, (char*)cmd.c_str(),NULL,NULL,TRUE,0,NULL,NULL,&si,&pi)) { cout << "CreateProcess失败" << endl; return false; } CloseHandle(hWrite); char buffer[128]={0}; DWORD bytesRead; bool bFindIt = false; bool bFindEnd = false; char *pBegin = NULL; ////ofstream ofile("c:\\\\out2.txt", ios_base::binary); cout << "Waiting..." << endl; //WaitForSingleObject(hRead,INFINITE); while (ReadFile(hRead,(LPVOID)&buffer,127,&bytesRead,NULL)) { buffer[bytesRead] = ‘\\0‘; ////ofile << (char*)buffer; ////continue; if(!bFindIt && (pBegin = strstr(buffer, g_name))) { system("cls"); bFindIt = true; char *pEnd = strstr(pBegin, "\\r\\n\\r\\n\\r\\n"); //每个class间至少3个 if(pEnd) { *(pEnd+6) = ‘\\0‘; bFindEnd = true; } cout << "class" << pBegin; continue; } if(bFindIt && !bFindEnd) { char *pEnd = strstr(buffer, "\\r\\n\\r\\n\\r\\n"); if(pEnd) { *(pEnd+6) = ‘\\0‘; bFindEnd = true; } cout << (char*)buffer; } } ////ofile.close(); if(false == bFindIt) cout << "未找到class" << g_name << endl << endl; return true; } int main(int argc, char*argv[]) { if(argc != 3) goto end; char *cppPath = argv[1]; while(*cppPath) cppPath++; if(cppPath - argv[1] < 5 || _strnicmp(cppPath-4, ".cpp", 4)) goto end; if(*argv[2] == ‘\\0‘) goto end; else _snprintf(g_name, 100, " %s\\t", argv[2]); char cmd[201] = {}; _snprintf(cmd, 200, "D:\\\\VS\\\\VS2013\\\\VC\\\\bin\\\\classLayout.bat \\"%s\\" \\"%s\\"", argv[1], argv[2]); CMDLine(cmd); return 0; end: cout << "error: 输入参数不正确" << endl; return 0; }
- 里面的ofile用来将所有捕获到的内容输出到文件的,想打开它,取消里面的////注释即可!!!
- 里面的_snprintf(g_name, 100, " %s\\t", argv[2]),是为了尽可能查找到类名,若改为"class %s\\t",有时会找不到,因为ReadFile是按块读取的,两个块有可能从"class %s"中间断开。。。我们这样减小了这种可能,,当然,只是减小而已。
- 这也会过滤error warning等
- struct的内存布局输出前缀也是"class"
编译生成clsLayout.exe后,Editplus里添加工具,如下:
$(CurSel)是鼠标选择的文本。。。
在Visual Studio里也可以配置的,通过:工具 - 外部工具 - 添加 。。。这里就略了
使用:调用该工具前,必须先用鼠标框选上你想看的类名!!然后点击工具图标或按快捷键Ctrl+5等。
使用动图:
以上是关于Editplus配置VC++ 与/d1reportSingleClassLayout的主要内容,如果未能解决你的问题,请参考以下文章
在Editplus中配置java的(带包)编译(javac)和执行(java)的方法