Windows 应用程序入口函数
GUI(Graphical User Interface)运用,连接器选项:/SUBSYSTEM:WINDOWS
CUI(Console User Interface)运用,连接器选项:/SUBSYSTEM:CONSOLE
_tWinMain 与 _tmain 函数声明
Int WINAPI _tWinMain(
HINSTANCE hInstanceExe,
HINSTANCE,
PTSTR pszCmdLine,
int nCmdShow);
int _tmain(
int argc,
TCHAR *argv[],
TCHAR *envp[]);
Windows 的动态链接库(Dynamic-Link Library)
一部分知识要点来源于《Windows 核心编程(第五版)》
用途
(1)拓展了应用程序的特点
(2)简单化了项目风险管理
(3)有利于节约运行内存
(4)推动了自然资源的共享资源
(5)推动了本土化
(6)有利于处理服务平台间的差别
(7)可以用以独特目地
留意
(1)建立 DLL,实际上是在建立可供一个可实行控制模块读取的函数
(2)当一个控制模块给予一个内存分配函数(malloc、new)的情况下,它一定与此同时给予另一个内存优化函数(free、delete)
(3)在应用 C 和 C 混编的情况下,要应用 extern “C” 修饰符
(4)一个 DLL 可以导出来函数、自变量(防止导出来)、C 类(导出导进必须同c语言编译器,不然防止导出来)
(5)DLL 控制模块:cpp 文档中的 ._declspec(dllexport) 写在 include 库函数以前
(6)启用 DLL 的可实行控制模块:cpp 文档的 ._declspec(dllimport) 以前不应该界定 MYLIBAPI
载入 Windows 程序流程的检索次序
1、包括可执行程序的文件目录
2、Windows 的系统目录,可以根据 GetSystemDirectory 获得
3、16 位的系统目录,即 Windows 文件目录中的 System 根目录
4、Windows 文件目录,可以根据 GetWindowsDirectory 获得
5、过程的当前目录
6、PATH 系统变量中所列举的文件目录
DLL 入口函数
DllMain 函数
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch(fdwReason)
{
case DLL_PROCESS_ATTACH:
// 第一次将一个DLL投射到过程详细地址室内空间时启用
// The DLL is being mapped into the process\' address space.
break;
case DLL_THREAD_ATTACH:
// 当过程建立一个进程的情况下,用以告知DLL实行与进程有关的复位(非主线任务程实行)
// A thread is bing created.
break;
case DLL_THREAD_DETACH:
// 系统进程 ExitThread 进程撤出前,将要停止的进程根据告知DLL实行与进程有关的清除
// A thread is exiting cleanly.
break;
case DLL_PROCESS_DETACH:
// 将一个DLL从过程的详细地址室内空间时启用
// The DLL is being unmapped from the process\' address space.
break;
}
return (TRUE); // Used only for DLL_PROCESS_ATTACH
}
写入卸载掉库
LoadLibrary、LoadLibraryExA、LoadPackagedLibrary、FreeLibrary、FreeLibraryAndExitThread 函数声明
// 载进库
HMODULE WINAPI LoadLibrary(
_In_ LPCTSTR lpFileName
);
HMODULE LoadLibraryExA(
LPCSTR lpLibFileName,
HANDLE hFile,
DWORD dwFlags
);
// 若想在通用性 Windows 服务平台(UWP)运用中载入 Win32 DLL,必须启用 LoadPackagedLibrary,而不是 LoadLibrary 或 LoadLibraryEx
HMODULE LoadPackagedLibrary(
LPCWSTR lpwLibFileName,
DWORD Reserved
);
// 卸载掉库
BOOL WINAPI FreeLibrary(
_In_ HMODULE hModule
);
// 卸载库和撤出进程
VOID WINAPI FreeLibraryAndExitThread(
_In_ HMODULE hModule,
_In_ DWORD dwExitCode
);
表明地连接到导出来标记
GetProcAddress 函数声明
FARPROC GetProcAddress(
HMODULE hInstDll,
PCSTR pszSymbolName // 只有接纳 ANSI 字符串数组,不可以是 Unicode
);
DumpBin.exe 查询 DLL 信息内容
在 VS 的开发者cmd 应用 DumpBin.exe 可查询 DLL 库的导出来段(导出的自变量、函数、类名的标记)、相对性虚拟注册地址(RVA,relative virtual address)。如:
LoadLibrary 与 FreeLibrary 流程表
LoadLibrary 与 FreeLibrary 流程图
LoadLibrary
FreeLibrary
DLL 库的撰写(导出来一个 DLL 控制模块)
DLL 库的撰写(导出来一个 DLL 控制模块) DLL 库函数
// MyLib.h
#ifdef MYLIBAPI
// MYLIBAPI 应当在所有 DLL 源代码的 include \"Mylib.h\" 以前被界定
// 所有函数/自变量已经被导出来
#else
// 这一库函数被一个exe源码控制模块包括,代表着所有函数/自变量被导进
#define MYLIBAPI extern \"C\" ._declspec(dllimport)
#endif
// 这儿界定一切的算法设计和符号
// 界定导出来的自变量(防止导出来自变量)
MYLIBAPI int g_nResult;
// 界定导出来函数原形
MYLIBAPI int Add(int nLeft, int nRight);
DLL 源代码
// MyLibFile1.cpp
// 包括规范Windows和C运作时库函数
#include <windows.h>
// DLL源代码文档导出来的函数和自变量
#define MYLIBAPI extern \"C\" ._declspec(dllexport)
// 包括导出来的算法设计、标记、函数、自变量
#include \"MyLib.h\"
// 将此DLL源码文档的编码放到这里
int g_nResult;
int Add(int nLeft, int nRight)
{
g_nResult = nLeft nRight;
return g_nResult;
}
DLL 库的应用(运作时动态链接 DLL)
DLL 库的应用(运作时动态链接 DLL)
// A simple program that uses LoadLibrary and
// GetProcAddress to access myPuts from Myputs.dll.
#include <windows.h>
#include <stdio.h>
typedef int (._cdecl *MYPROC)(LPWSTR);
int main( void )
{
HINSTANCE hinstLib;
MYPROC ProcAdd;
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
// Get a handle to the DLL module.
hinstLib = LoadLibrary(TEXT(\"MyPuts.dll\"));
// If the handle is valid, try to get the function address.
if (hinstLib != NULL)
{
ProcAdd = (MYPROC) GetProcAddress(hinstLib, \"myPuts\");
// If the function address is valid, call the function.
if (NULL != ProcAdd)
{
fRunTimeLinkSuccess = TRUE;
(ProcAdd) (L\"Message sent to the DLL functionn\");
}
// Free the DLL module.
fFreeResult = FreeLibrary(hinstLib);
}
// If unable to call the DLL function, use an alternative.
if (! fRunTimeLinkSuccess)
printf(\"Message printed from executablen\");
return 0;
}
运行库(Runtime Library)
典型性程序运行流程
(1)电脑操作系统建立过程,把决策权交到程序流程的入口(通常是运行库中的某一入口函数)
(2)入口函数对运行库和程序运行自然环境开展复位(包含堆、I/O、进程、全局变量结构这些)。
(3)入口函数复位后,启用 main 函数,正式开始程序执行行为主体一部分。
(4)main 函数实行结束后,回到到入口函数开展清洗工作中(包含全局变量析构、堆消毁、关掉I/O等),随后开展系统进程结束任务。
一个程序流程的 I/O 指代程序与外部的互动,包含文档、管程、互联网、命令、数据信号等。更理论地讲,I/O 指代电脑操作系统了解为 “文档” 的事情。
glibc 入口
_start -> ._libc_start_main -> exit -> _exit
在其中 main(argc, argv, ._environ) 函数在 __libc_start_main 里实行。
MSVC CRT 入口
int mainCRTStartup(void)
执行如下所示实际操作:
(1)复位和 OS 版本号相关的全局变量。
(2)复位堆。
(3)初始化 I/O。
(4)获得命令行参数和系统变量。
(5)复位 C 库的一些数据信息。
(6)启用 main 并纪录传参。
(7)查验问题并将 main 的传参回到。
C 语言表达运行库(CRT)
大概包括如下所示作用:
运行与撤出:包含入口函数及入口函数所依靠的别的函数等。
规范函数:有 C 语言表达标准的C语言标准库所具有的函数完成。
I/O:I/O 作用的封装形式和完成。
堆:堆的封装形式和完成。
语言表达完成:语言表达中一些独特作用的完成。
调节:完成调节作用的编码。
C语言标准库(ANSI C)
包括:
规范I/O(stdio.h)
文档实际操作(stdio.h)
标识符实际操作(ctype.h)
字符串数组实际操作(string.h)
数学课函数(math.h)
资源优化配置(stdlib.h)
格式转化(stdlib.h)
時间/日期(time.h)
结论(assert.h)
多种类型上的参量(limits.h & float.h)
拉长主要参数(stdarg.h)
非部分自动跳转(setjmp.h)
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。