tools: generate cross-compiled macros for header file
发布日期:2021-06-30 22:16:54 浏览次数:2 分类:技术文章

本文共 8740 字,大约阅读时间需要 29 分钟。

前言

在用vs写一个简单工厂模式的demo, 随着case的增多,要新建更多的类。

vs为了防止交叉编译,为头文件生成的交叉编译宏为#pragma once
我写的是平台无关的类,到了gcc下,编译器不认得#pragma once
这时,必须自己手工将#pragma once,定义和头文件名相关的交叉编译宏
新建的类超过几个后,感觉真不好,浑身不舒服:)
花了2个小时,写了个工程,根据头文件名称生成交叉编译宏,用起来,感觉好多了^_^

效果

这里写图片描述

这里写图片描述

demo工程

编译环境:vs2010 or vs2017 + win32sdk

工程预览

// hw.cpp : Defines the entry point for the application.//#include "stdafx.h"#include 
#include
#include
#include
#include
#pragma comment(lib, "user32.lib")#include
#include
#include
#pragma comment(lib, "Shell32.lib")#include "resource.h"#include "constDefine.h"HINSTANCE g_hInstance = NULL;HWND g_hMainWnd = NULL;char g_sz_user_input[MAXBYTE] = { '\0'};LRESULT CALLBACK MainDlgProc(HWND, UINT, WPARAM, LPARAM);void fnCenterWindow(HWND hWnd);void fnSetWndText(HWND hWnd, const TCHAR* pcTip);void fnSetCtrlText(int iCtrlId, const TCHAR* pcTip);bool gen_macro_for_header_file(const char* psz_header_file_name, std::string& str_macro);bool GetTempFolder(std::string &strTempFolder);BOOL fnIsFileExist(const char* pcFilePathName);BOOL fnSplitFilePathName( const char* pcPathName, std::string& strDriver, std::string& strDir, std::string& strFileNamePrefix, std::string& strFileNamePostfix);LRESULT OnInitDialog(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);LRESULT OnClose(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);LRESULT OnCancel(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);LRESULT OnOk(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);LRESULT OnDropFiles(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);// 做一些测试任务, 发行时,里面的内容会被关掉void fnTest_On_WinMain();int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){ srand(NULL); g_hInstance = hInstance; fnTest_On_WinMain(); return DialogBox(hInstance, (LPCTSTR)IDD_MAIN_DLG, GetDesktopWindow(), (DLGPROC)MainDlgProc);}LRESULT CALLBACK MainDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ BOOL bRc = TRUE; WORD wCtrlId = LOWORD(wParam); WORD wNotifyCode = HIWORD(wParam); HWND hSubWnd = (HWND)lParam; switch (message) { case WM_INITDIALOG: { OnInitDialog(hWnd, message, wParam, lParam); } break; case WM_COMMAND: switch (wCtrlId) { case IDCANCEL: OnCancel(hWnd, message, wParam, lParam); break; case IDOK: OnOk(hWnd, message, wParam, lParam); break; default: break; } break; case WM_CLOSE: OnClose(hWnd, message, wParam, lParam); break; case WM_DROPFILES: OnDropFiles(hWnd, message, wParam, lParam); break; default: bRc = FALSE; break; } return bRc;}void fnCenterWindow(HWND hWnd){ HWND hwndOwner; RECT rc; RECT rcDlg; RECT rcOwner; hwndOwner = GetParent(hWnd); if (NULL == hwndOwner) { hwndOwner = GetDesktopWindow(); } GetWindowRect(hwndOwner, &rcOwner); GetWindowRect(hWnd, &rcDlg); CopyRect(&rc, &rcOwner); OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top); OffsetRect(&rc, -rc.left, -rc.top); OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom); SetWindowPos(hWnd, HWND_TOP, rcOwner.left + (rc.right / 2), rcOwner.top + (rc.bottom / 2), 0, 0, SWP_NOSIZE);}void fnSetCtrlText(int iCtrlId, const TCHAR* pcTip){ HWND hWnd = NULL; if (NULL != g_hMainWnd) { hWnd = GetDlgItem(g_hMainWnd, iCtrlId); fnSetWndText(hWnd, pcTip); }}void fnSetWndText(HWND hWnd, const TCHAR* pcTip){ if (NULL != hWnd) { SetWindowText(hWnd, (NULL != pcTip) ? pcTip : _T("")); }}LRESULT OnInitDialog(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ g_hMainWnd = hWnd; fnSetWndText(g_hMainWnd, G_STR_PROG_NAME); fnCenterWindow(hWnd); return S_OK;}LRESULT OnClose(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ EndDialog(hWnd, LOWORD(wParam)); return S_OK;}LRESULT OnCancel(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ EndDialog(hWnd, LOWORD(wParam)); return S_OK;}LRESULT OnDropFiles(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ POINT pt; char sz_user_input[MAXBYTE] = { '\0'}; char* psz_find = NULL; UINT uFilesCnt = 0; UINT uIndex = 0; HDROP hDropFile = (HDROP)wParam; DragQueryPoint(hDropFile, &pt); uFilesCnt = DragQueryFile(hDropFile, -1, (LPSTR) NULL, 0); for (uIndex = 0; uIndex < uFilesCnt; uIndex++) { memset(sz_user_input, 0, sizeof(sz_user_input)); DragQueryFile(hDropFile, uIndex, sz_user_input, sizeof(sz_user_input));#if 0 // 只保留头文件名 e.g. x.h memset(g_sz_user_input, 0, sizeof(g_sz_user_input)); psz_find = strrchr(sz_user_input, '\\'); if (NULL != psz_find) { strcpy(g_sz_user_input, psz_find + 1); }#else // 既然是拖入文件, 由用户再二次编辑头文件名全路径后,再生成宏 // e.g. drop file is "c:\x_dir1\x_dir2\x.h" // edit to "x_dir2\x.h" then gen macro as "__X_DIR2_X_H__" strcpy(g_sz_user_input, sz_user_input);#endif fnSetCtrlText(IDC_EDIT, g_sz_user_input); fnSetCtrlText(IDC_STATIC_TIP, "请点击按钮\"生成编译宏\""); break; } DragFinish(hDropFile); return S_OK;}BOOL fnIsFileExist(const char* pcFilePathName){ BOOL bRc = FALSE; HANDLE hFile = INVALID_HANDLE_VALUE; do { if (NULL == pcFilePathName) { break; } hFile = CreateFile(pcFilePathName, // file name GENERIC_READ, // open for reading 0, // do not share NULL, // default security OPEN_EXISTING, // existing file only FILE_ATTRIBUTE_NORMAL, // normal file NULL); // no template if ((NULL == hFile) || (INVALID_HANDLE_VALUE == hFile)) { break; } CloseHandle(hFile); hFile = INVALID_HANDLE_VALUE; bRc = TRUE; } while (0); return bRc;}void fnTest_On_WinMain(){}BOOL fnSplitFilePathName( const char* pcPathName, std::string& strDriver, std::string& strDir, std::string& strFileNamePrefix, std::string& strFileNamePostfix){ char szPathName[MAX_PATH] = { '\0'}; char szDriver[MAX_PATH] = { '\0'}; /// 这个缓冲区要整大点, 要不执行结果不对. char szDir[MAX_PATH] = { '\0'}; char szFileNamePrefix[MAX_PATH] = { '\0'}; char szFileNamePostfix[MAX_PATH] = { '\0'}; if (NULL == pcPathName) { return FALSE; } strcpy(szPathName, pcPathName); // _splitpath 的反函数_makepath _tsplitpath(szPathName, szDriver, szDir, szFileNamePrefix, szFileNamePostfix); strDriver = szDriver; strDir = szDir; strFileNamePrefix = szFileNamePrefix; strFileNamePostfix = szFileNamePostfix; /** note * csPathName = c:\subDir1\subDir2\subDir3\test1.dat * csDriver = c: * csDir = \subDir1\subDir2\subDir3\ * csFileNamePrefix = test1 * csFileNamePostfix = .dat */ return TRUE;}LRESULT OnOk(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ int iFileIndex = 0; HWND hEdit = NULL; char szBuf[MAXBYTE] = { '\0'}; std::string str_macro; std::string strTempFilePathName; FILE* pfile = NULL; SHELLEXECUTEINFOA ShExecInfo = { 0}; fnSetCtrlText(IDC_STATIC_TIP, "..."); hEdit = ::GetDlgItem(g_hMainWnd, IDC_EDIT); ::GetWindowText(hEdit, g_sz_user_input, sizeof(g_sz_user_input)); if (gen_macro_for_header_file(g_sz_user_input, str_macro)) { GetTempFolder(strTempFilePathName); sprintf(szBuf, "gen_macro_for_header_%d.txt", rand()); strTempFilePathName += szBuf; pfile = fopen(strTempFilePathName.c_str(), "w"); if (NULL != pfile) { fwrite(str_macro.data(), str_macro.length(), sizeof(char), pfile); fclose(pfile); pfile = NULL; ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFOA); ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS; ShExecInfo.hwnd = NULL; ShExecInfo.lpVerb = NULL; ShExecInfo.lpFile = "notepad.exe"; ShExecInfo.lpParameters = strTempFilePathName.c_str(); ShExecInfo.lpDirectory = NULL; ShExecInfo.nShow = SW_SHOWNORMAL; ShExecInfo.hInstApp = NULL; ShellExecuteEx(&ShExecInfo); WaitForSingleObject(ShExecInfo.hProcess,INFINITE); DeleteFileA(strTempFilePathName.c_str()); } } else { fnSetCtrlText(IDC_STATIC_TIP, "请输入头文件名称 :)"); } return S_OK;}bool GetTempFolder(std::string &strTempFolder){ char sz_buf[MAX_PATH * 2] = { '\0'}; GetTempPathA(sizeof(sz_buf), sz_buf); strTempFolder = sz_buf; return true;}bool gen_macro_for_header_file(const char* psz_header_file_name, std::string& str_macro){ bool b_rc = false; int8_t sz_buf[MAXBYTE * 4] = { '\0'}; std::string str_tmp = ""; std::string str_macro_name = ""; do { str_macro = ""; if ((NULL == psz_header_file_name) || (strlen(psz_header_file_name) <= 0)) { break; } sprintf((char*)sz_buf, "// @file : %s\n", psz_header_file_name); str_macro += (char*)sz_buf; sprintf((char*)sz_buf, "// @brief : ...\n"); str_macro += (char*)sz_buf; str_tmp = psz_header_file_name; std::transform(str_tmp.begin(), str_tmp.end(), str_tmp.begin(), ::toupper); std::replace(str_tmp.begin(), str_tmp.end(), ':', '_'); std::replace(str_tmp.begin(), str_tmp.end(), '.', '_'); std::replace(str_tmp.begin(), str_tmp.end(), '\\', '_'); str_macro_name += "__"; str_macro_name += str_tmp.c_str(); str_macro_name += "__"; sprintf((char*)sz_buf, "#ifndef %s\n", str_macro_name.c_str()); str_macro += (char*)sz_buf; sprintf((char*)sz_buf, "#define %s\n", str_macro_name.c_str()); str_macro += (char*)sz_buf; str_macro += "\r\n\r\n"; sprintf((char*)sz_buf, "#endif // #define %s\n", str_macro_name.c_str()); str_macro += (char*)sz_buf; b_rc = true; } while (0); return b_rc;}

转载地址:https://lostspeed.blog.csdn.net/article/details/79146181 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:java call so :only use one struct as input and output parameter
下一篇:stdint dot h 's data type define

发表评论

最新留言

感谢大佬
[***.8.128.20]2024年04月13日 00时43分25秒