吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3065|回复: 6
收起左侧

[C&C++ 转载] 不包含windows.h和window.h内的任何头文件,弹框 “Hello, world!”

  [复制链接]
天上飞来一只 发表于 2020-10-22 15:27
本帖最后由 天上飞来一只 于 2020-10-22 15:36 编辑

前言:windows应用程序下,不包含windows.hwindow.h内的任何头文件,弹框 “Hello, world!本文主要基于 vs2015 生成的windows应用程序的空工程进行研究,以提高对基础知识的理解。


一、VS基础配置1.打开VS2015,新建项目----win32控制台应用程序----windows应用程序,附加选项,空项目
图片1.png


二、windows应用程序的主入口函数wWinMain写任何一个函数应该有一个该函数的入口了。我们知道控制台的入口函数是main()函数,那么在写Windows应用程序也是main()吗?
回答当然不是了。我们用的是SDK中的WinMain()函数参考MSDN的说明
[C] 纯文本查看 复制代码
int WINAPI WinMain( 
HINSTANCE hInstance, // handle to current instance 
HINSTANCE hPrevInstance, // handle to previous instance 
LPSTR lpCmdLine, // command line 
int nCmdShow // show state
);
Requirements 
Windows NT/2000/XP: Included in Windows NT 3.1 and later.
           Windows 95/98/Me: Included in Windows 95 and later.
            Header: Declared in Winbase.h; include Windows.h.

MSDN上已经说明需要包含 Winbase.h或者Windows.h. 那我们需要的挑战就是不使用任何头文件,也能正常弹出提示框MessageBox



三、具体流程1、先写主函数内的内容int APIENTRY WinMain(_In_ HINSTANCE hInstance,        _In_opt_ HINSTANCE hPrevInstance,        _In_ LPWSTR    lpCmdLine,        _In_ int       nCmdShow){        //MessageBox(NULL, TEXT("hello world"), TEXT("标题"), MB_OK);        return 0;}2、如果直接选择编译以上问题,相信大家看VS提示输出窗口是一大堆,莫名其妙的错误提示 1.png 这么多语法错误、未声明的标识符 为啥???现在我会一点一点的挽回那失去的耐心!优先解决掉未声明的标识符

3、解决提示“_In_”: 未声明的标识符的问题     

    _in 输入参数    _out 输出参数
    _opt 参数是可选的,就是可以为NULL
    _ecount 所指向的缓存的元素个素 也就是括号里的数字
    这些宏都被定义为空,只是让程序更容易理解!
解放方法:  

宏定义

#define _In_

#define _In_opt_  


4、C语言语法基础知识在使用函数之前应该先声明,那么WinMain函数,同样也需要声明,OK,加上
[Asm] 纯文本查看 复制代码
//宏定义
#define _In_
#define _In_opt_

//函数声明
int APIENTRY WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
        _In_ LPWSTR lpCmdLine, _In_ int nShowCmd);

//入口函数
int APIENTRY WinMain(_In_ HINSTANCE hInstance,
        _In_opt_ HINSTANCE hPrevInstance,
        _In_ LPWSTR    lpCmdLine,
        _In_ int       nCmdShow)
{
        //MessageBox(NULL, TEXT("hello world"), TEXT("标题"), MB_OK);
        return 0;
}

5、继续F7编译,还是提示很多报错,不要放弃,继续解决错误
1.png

大家可以新的提示“HINSTANCE”: 未声明的标识符,依次解决掉WinMain函数的所有类型

解决方法:

HINSTANCE“句柄型”数据类型HWND 是一个基本类型一般指窗口句柄
LPSTR一种字符串数据类型
LPCSTR一种常量字符串数据类型
LPWSTR是wchar_t字符串数据类型
LPCWSTR 常量wchar_t字符串数据类型

UINT是无符号整型数据类型

依次自定义类型
[C] 纯文本查看 复制代码
typedef void *HINSTANCE;
typedef void *HWND;
typedef char *LPSTR;
typedef const char *LPCSTR;
typedef wchar_t *LPWSTR;
typedef const wchar_t *LPCWSTR;
typedef unsigned int UINT;


6、继续F7编译,提示报错
1.png

看到这么多错误,还能坚持下来的同学,是最棒的! 可以看到提示“WinMain”: 必须是“__stdcall”

解决:
__stdcall是函数调用约定的一种,函数调用约定主要约束了两件事:1.参数传递顺序2.调用堆栈由谁(调用函数或被调用函数)清理

那么可以得出APIENTRY就是表示__stdcall,定义#define APIENTRY __stdcall
[C++] 纯文本查看 复制代码
//宏定义
#define _In_
#define _In_opt_
#define APIENTRY __stdcall
//自定义数据类型
typedef void *HINSTANCE;
typedef void *HWND;
typedef char *LPSTR;
typedef const char *LPCSTR;
typedef wchar_t *LPWSTR;
typedef const wchar_t *LPCWSTR;
typedef unsigned int UINT;
//函数声明
int APIENTRY WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
        _In_ LPWSTR lpCmdLine, _In_ int nShowCmd);
//函数入口
int APIENTRY WinMain(_In_ HINSTANCE hInstance,
        _In_opt_ HINSTANCE hPrevInstance,
        _In_ LPWSTR    lpCmdLine,
        _In_ int       nCmdShow)
{
        //MessageBox(NULL, TEXT("hello world"), TEXT("标题"), MB_OK);
        return 0;
}


7、添加代码继续编译F7,无错误
1.png

8、终于到了MessageBox阶段,取消注释,编译F7等待报错。
1.png
MessageBox找不到标识符,MessageBox是函数,同样也需要声明,这里需要注意MessageBox实际分为2个版本:
[Asm] 纯文本查看 复制代码
int WINAPI MessageBoxA(_In_opt_ HWND hWnd, _In_opt_ LPCSTR lpText, _In_opt_ LPCSTR lpCaption, _In_ UINT uType);
int WINAPI MessageBoxW(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType);
需要进行宏定义
#ifdef UNICODE
#define MessageBox  MessageBoxW
#else
#define MessageBox  MessageBoxA
#endif

[Asm] 纯文本查看 复制代码
解决:NULL TEXT,MB_OK未知标识符,宏定义走起
#define __TEXT(quote) L##quote     
#define TEXT(quote) __TEXT(quote)   
#define MB_OK   0x00000000L
#define  NULL 0
[/size][/font]
[font=宋体][size=12.0000pt]#define WINAPI __stdcall


9、编译,报错
2.png
解决:
小知识点,MessageBoxA很古老,为了能够正确实现C++代码调用其他C语言代码,在MessageBoxA和MessageBoxW上必须声明C,即extern "C"

10、完整代码,求爱心!   WindowsMain.rar (622 Bytes, 下载次数: 14)
1.png

免费评分

参与人数 3吾爱币 +5 热心值 +2 收起 理由
笙若 + 1 + 1 谢谢@Thanks!
huangsijun17 + 2 感谢发布原创作品,吾爱破解论坛因你更精彩!
iteamo + 2 + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

JuncoJet 发表于 2020-10-22 16:46
你这强迫症要治,用goasm吧
qbnw 发表于 2020-10-22 17:21
chen4321 发表于 2020-10-22 17:28
痴情总被无情伤 发表于 2021-2-24 23:46
你这是把弹窗要用到的头文件的内容都搬出来了啊
wCoding 发表于 2021-2-26 08:38
随着功能的增加,就全搬过来了。
AA_BB_2AB 发表于 2021-4-2 15:23
谢谢,祝您身体健康!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 18:30

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表