1.封装WinMain至动态链接库
1.封裝WinMain至動態(tài)鏈接庫
DND的前言:
??? DND是定位于Windows平臺的2d游戲引擎,使用C++和DirectX 11實(shí)現(xiàn),編譯器使用vs2015。保留了一些3d功能,適合做一些pc上的高效率2d游戲。目前已經(jīng)是第n遍重寫引擎代碼了(n>= 5),在這次重寫的機(jī)會,也以發(fā)博客的方式記錄自己的學(xué)習(xí)筆記,同時(shí)也希望我所分享的一些技術(shù)能幫助到大家。
? 本章前言:
??? 在windows編程下,一般項(xiàng)目以控制臺窗口、Windows窗口、動態(tài)鏈接庫、靜態(tài)鏈接庫四種形式為目標(biāo)生成。DND引擎使用動態(tài)鏈接庫的方式生成,而使用DND引擎的程序直接建立Windows窗口(即入口函數(shù)為WinMain)。雖然可以選擇以main作為入口,但是一開始出現(xiàn)的控制臺窗口并不好處理掉(隱藏掉還是會閃一下,程序員們怎么能忍,一下格比就下去了)。所以比較好的方式是以WinMain作為入口,然后再建立Console窗口作為調(diào)試信息窗口(這個窗口可選是否建立,一般調(diào)試的時(shí)候建立,發(fā)布后肯定不需要建立了)。但是作為引擎必須將WinMain封裝起來,HGE引擎就沒有處理這一點(diǎn),導(dǎo)致使用難度提高了不少:-),想想我大一的時(shí)候。
? 最終效果:
??? 用戶建立Win32項(xiàng)目之后,只需要如下使用便可實(shí)現(xiàn)程序入口:
//main.cpp
#include <DND.h>
DNDMain()
{
??? //主函數(shù)內(nèi)容
}
//endmain.cpp
? 實(shí)現(xiàn)過程:
??? 由于使用鏈接庫的程序(后面稱為用戶程序)是Win32窗口程序,它需要查找WinMain函數(shù)符號作為函數(shù)入口。但我們將其放入了動態(tài)鏈接庫,如下面所示:
//WinMain的定義式,放在了DND的項(xiàng)目中
#include <windows.h>
int WINAPIWinMain(HINSTANCEhinstance, HINSTANCE,LPSTR, int)
{
//一些內(nèi)容
}
//end
??? 所以我們需要導(dǎo)出函數(shù)符號,右鍵項(xiàng)目文件->添加新建項(xiàng)->代碼->模塊定義文件(.def)。在def文件中添加導(dǎo)出WinMain,內(nèi)容如下所示:
//export.def
LIBRARY"DND"
EXPORTS
WinMain
//end export.def
??? 這樣入口就會從庫中的WinMain入口函數(shù)執(zhí)行。但是為了WinMain函數(shù)執(zhí)行我們形式入口函數(shù),需要從用戶執(zhí)行模塊取得形式入口函數(shù)指針。這里用到了GetProcAddress函數(shù),WinMain函數(shù)內(nèi)容如下:
int WINAPIWinMain(HINSTANCEhinstance, HINSTANCE,LPSTR, int)
{
??? void(*_func_dnd_main)(void);
??? //從執(zhí)行模塊獲取_func_dnd_main函數(shù)
??? _func_dnd_main = (void(*)())GetProcAddress(hinstance,"_func_dnd_main");
??? if (!_func_dnd_main)
??? {
??????? //錯誤處理
??????? return 0;
??? }
??? //執(zhí)行形式入口函數(shù)
??? _func_dnd_main();
??? return 0;
}
??? 注意,在這里這個函數(shù)名字叫_func_dnd_main,當(dāng)然你也可以隨便寫,只要各處統(tǒng)一就行了。在執(zhí)行形式入口函數(shù)之前或之后,還可以執(zhí)行引擎相關(guān)的一些函數(shù),保證在用戶的代碼執(zhí)行之前或之后執(zhí)行。
??? 接著,我們需要在用戶程序中實(shí)現(xiàn)這個_func_dnd_main函數(shù)的定義,也就是形式入口函數(shù)。像下面這樣:
extern "C"__declspec(dllexport)void _func_dnd_main()
{
}
??? 其中extern “C”讓函數(shù)名以C的方式編譯,__declspec(dllexport)使這個函數(shù)從用戶程序中導(dǎo)出。為了簡化寫法,再定義一個宏DNDMain:
#defineDNDMainextern"C"__declspec(dllexport)void _func_dnd_main
??? 這樣,形式入口函數(shù)的寫法就變成了最終效果中的寫法,用起來十分簡單。
? 示例:
??? 打上一個斷點(diǎn),可以發(fā)現(xiàn)程序執(zhí)行到了我們想執(zhí)行的地方,并且整個程序也只有5行。眼花了,8行:-)。?
?
?
作者:略游
日期:17-05-20
QQ:1339484752
總結(jié)
以上是生活随笔為你收集整理的1.封装WinMain至动态链接库的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: GCC选项_-Wl,-soname
- 下一篇: 2.创建适合游戏的窗口和消息循环