1.封装WinMain至动态链接库

DND的前言:

DND是定位于Windows平台的2d游戏引擎,使用C++和DirectX 11实现,编译器使用vs2015。保留了一些3d功能,适合做一些pc上的高效率2d游戏。目前已经是第n遍重写引擎代码了(n>= 5),在这次重写的机会,也以发博客的方式记录自己的学习笔记,同时也希望我所分享的一些技术能帮助到大家。

本章前言:

在windows编程下,一般项目以控制台窗口、Windows窗口、动态链接库、静态链接库四种形式为目标生成。DND引擎使用动态链接库的方式生成,而使用DND引擎的程序直接建立Windows窗口(即入口函数为WinMain)。虽然可以选择以main作为入口,但是一开始出现的控制台窗口并不好处理掉(隐藏掉还是会闪一下,程序员们怎么能忍,一下格比就下去了)。所以比较好的方式是以WinMain作为入口,然后再建立Console窗口作为调试信息窗口(这个窗口可选是否建立,一般调试的时候建立,发布后肯定不需要建立了)。但是作为引擎必须将WinMain封装起来,HGE引擎就没有处理这一点,导致使用难度提高了不少:-),想想我大一的时候。

最终效果:

用户建立Win32项目之后,只需要如下使用便可实现程序入口:

//main.cpp

#include <DND.h>

DNDMain()

{

//主函数内容

}

//endmain.cpp

实现过程:

由于使用链接库的程序(后面称为用户程序)是Win32窗口程序,它需要查找WinMain函数符号作为函数入口。但我们将其放入了动态链接库,如下面所示:

//WinMain的定义式,放在了DND的项目中

#include <windows.h>

int WINAPIWinMain(HINSTANCEhinstance, HINSTANCE,LPSTR, int)

{

//一些内容

}

//end

所以我们需要导出函数符号,右键项目文件->添加新建项->代码->模块定义文件(.def)。在def文件中添加导出WinMain,内容如下所示:

//export.def

LIBRARY"DND"

EXPORTS

WinMain

//end export.def

这样入口就会从库中的WinMain入口函数执行。但是为了WinMain函数执行我们形式入口函数,需要从用户执行模块取得形式入口函数指针。这里用到了GetProcAddress函数,WinMain函数内容如下:

int WINAPIWinMain(HINSTANCEhinstance, HINSTANCE,LPSTR, int)

{

void(*_func_dnd_main)(void);

//从执行模块获取_func_dnd_main函数

_func_dnd_main = (void(*)())GetProcAddress(hinstance,"_func_dnd_main");

if (!_func_dnd_main)

{

//错误处理

return 0;

}

//执行形式入口函数

_func_dnd_main();

return 0;

}

注意,在这里这个函数名字叫_func_dnd_main,当然你也可以随便写,只要各处统一就行了。在执行形式入口函数之前或之后,还可以执行引擎相关的一些函数,保证在用户的代码执行之前或之后执行。

接着,我们需要在用户程序中实现这个_func_dnd_main函数的定义,也就是形式入口函数。像下面这样:

extern "C"__declspec(dllexport)void _func_dnd_main()

{
}

其中extern “C”让函数名以C的方式编译,__declspec(dllexport)使这个函数从用户程序中导出。为了简化写法,再定义一个宏DNDMain:

#defineDNDMainextern"C"__declspec(dllexport)void _func_dnd_main

这样,形式入口函数的写法就变成了最终效果中的写法,用起来十分简单。

示例:

打上一个断点,可以发现程序执行到了我们想执行的地方,并且整个程序也只有5行。眼花了,8行:-)。

作者:略游

日期:17-05-20

QQ:1339484752

1.封装WinMain至动态链接库相关推荐

  1. 封装caffe-windows-master为动态链接库

    2016.12.14: 代码已知bug: 由于类中有全局变量,声明多个对象时,全局变量指向会改变,造成结果错误并且有内存泄漏.因此该份代码只能声明一个Classifier对象. 新的代码已经重新封装, ...

  2. Delphi中DLL封装业务逻辑的实现

      三层结构是开发C/S或B/S系统经常采用的策略,这种分层方式将系统分为用户服务.业务服务和数据服务三部分,能够解决客户端与服务器结构维护成本问题.改善客户端与服务器结构延展性问题:解决应用逻辑重复 ...

  3. 用VB.NET(Visual Basic 2010)封装EXCEL VBA为DLL_COM组件(一)

    vb.net教程https://www.xin3721.com/eschool/vbnetxin3721/ 为了保护自己辛辛苦苦编写的Excel VBA代码不被盗用,我们需要对Excel VBA代码进 ...

  4. 用VB.NET(Visual Basic 2010)封装EXCEL VBA为DLL_COM组件(一)

    为了保护自己辛辛苦苦编写的Excel VBA代码不被盗用,我们需要对Excel VBA代码进行加密.通常的做法是利用给工程设置密码的方法实现加密,对于这类加密方法,由于存在安全度低.易破解等问题,因此 ...

  5. 框架原理第一讲,熟悉常用的设计方式.(以MFC框架讲解)

    框架原理第一讲,熟悉常用的设计方式.(以MFC框架讲解) 一丶什么是框架,以及框架的作用 什么是框架? 框架,简而言之就是把东西封装好了,使用框架开发可以快速开发程序,例如MFC程序的双击写代码. 为 ...

  6. 驱动级模拟驱动级模拟:直接读写键盘的硬件端口!

    驱动级模拟驱动级模拟:直接读写键盘的硬件端口! 有一些使用DirectX接口的游戏程序,它们在读取键盘操作时绕过了windows的消息机制,而使用DirectInput.这是因为有些游戏对实时性控制的 ...

  7. MFC六大核心机制之一:MFC程序的初始化

    很多做软件开发的人都有一种对事情刨根问底的精神,例如我们一直在用的MFC,很方便,不用学太多原理性的知识就可以做出各种窗口程序,但喜欢钻研的朋友肯定想知道,到底微软帮我们做了些什么,让我们在它的框架下 ...

  8. c#调用c语言的自定义函数,[转]在C#中调用C语言函数(静态调用Native DLL,Windows Microsoft.Net平台)...

    对于不太了解.Net的人,如果想要了解.Net,我必须给他介绍P/Invoke.P/Invoke是什么呢?简单地说,就是在.Net中调用本地代码(Native code)的一种解决方案.所谓" ...

  9. labiview ni python_LabVIEW到底有哪些优势导致他用户量这么少但是长期不消失?

    这真的是个好问题,我非常喜欢! 首先表明本人和LabVIEW母公司的NI的利益关系,以免行文作答过程中中由于热爱,而过于吹爆LabVIEW引起负面反感情绪:本人非NI公司的雇员,也不持有任何NI公司的 ...

最新文章

  1. 使用CSS3美化复选框checkbox
  2. Python 8 协程,异步IO,Paramiko
  3. The Relation Between Gradient Descent and Cost Funtion(To be continued)
  4. python 查看PIL包下的 Image.py 模块时 import _builtin__显示 python version 3.6 does not have module __builtin__
  5. U-Boot启动过程--详细版的完全分析
  6. app测试之耗电量测试
  7. 华为P30 Pro真机上手谍照曝光 这颜值打几分?
  8. 计算机采用逻辑元件的发展顺序是,全国计算机等级考试一级选择题以及答案
  9. Copy-On-Write容器之一:CopyOnWriteArrayList
  10. As-Conformal-As-Possible Surface Registration
  11. 机器学习常用损失函数
  12. openvino踩坑记(ImportError: DLL load failed while importing ie_api)
  13. 3229: 硬币组合
  14. 数据库系统的基本组成
  15. 满地鸡毛的一年 || 转行Android之路
  16. 当代年轻人到底怎么跨越阶层?
  17. 服务器的内存和硬盘哪个更重要,[内存与硬盘区别] 内存和硬盘哪个重要
  18. 词法分析二(词法分析程序)
  19. 无人机实验平台(七) 实验平台的坐标转换(上)
  20. 杀不死的Service

热门文章

  1. java json的使用方法_JAVA编写JSON常用的三种方法
  2. 三十五、深入Java中的泛型(下篇)
  3. 微信小程序开发的快速步骤方法和最大的坑
  4. CVPR 2020 | 自适应聚合网络AANet:更高效的立体匹配
  5. IEMLRN:基于图像增强的句子语义表示
  6. AAAI 2018论文解读 | 基于文档级问答任务的新注意力模型
  7. pytorch datasets.ImageFolder,DataLoader形成的tensor是什么样的?
  8. SpringBoot接口参数校验
  9. 给echarts添加筛选时间控件时,控件不显示,并设置数据库无数据时echarts模块显示暂无数据
  10. 《移动应用开发》实验报告——轮播图