引子

“Windows 程序分为‘程序代码’和‘UI(User Interface)资源’两大部份,两部份最后以RC编译器(资源编译器)整合为一个完整的EXE 文件。所谓UI 资源是指功能菜单、对话框外貌、程序图标、光标形状等等东西。这些UI 资源的实际内容(二进制代码)系借助各种工具产生,并以各种扩展名存在,如.ico、.bmp、.cur 等等。程序员必须在一个所谓的资源描述档(.rc)中描述它们。RC 编译器读取RC 档的描述后将所有UI资源档集中制作出一个.RES 档,再与程序代码结合在一起,这才是一个完整的Windows可执行件。”

以上是侯捷先生在《深入浅出MFC》中关于windows程序开发流程的一段论述,我觉得他说的很是精辟,简明扼要的说清楚了Windows程序的两方面,特放在此与大家分享。下文中我还还要引用他的这本书中的内容。

我的忠告

说到windows编程,我认为首先要先了解清楚windows程序由生到死的整个机制和过程。当你对微软定的这个“游戏规则”了然于胸后,我想后面的学习将会对你来说很轻松。所以,请你认真看懂这一回的内容。

这两回我要交代的东西还真是不少,既要讲解windows程序机制又要引进windows中很多概念。在此我很欣赏王爽老师的教学观点——知识屏蔽。有关概念等到用的时候我再解释,不用的我先不提,很多书开始都是先一股脑的把很多概念都抛出来,让读者看的迷迷糊糊的,反而增加了读者的畏惧心理。我认为一边用一边在介绍概念反而会让读者更好理解一点。(至少对于我来说是这样)。

我还要再强调一下,这两回的的主要内容是讲解运行机制,我打算以一边讲机制一边读程序的方式来进行。考虑到大家对很多概念和很多函数都是第一次接触,所以我只是以“写意”形式来搞。只要你对这机制和过程能宏观和整体上掌握了解,那你就是成功的。遇到概念我会简单介绍(小字内容是对概念的扩展,有余力的读者可以看看),看了不理解,这很正常,请继续看下去,从下面我对概念的运用上你再慢慢体会这概念的含义,这个概念理解过程正如我们小的时候学说话,听得多了自然就懂了(现在不必一时纠结于此)。很多函数我只说它的作用,具体用法和为什么这么用请你在这一回不要操心(函数用法我以后会讲解,以后你看得多了,闭着眼都能写出来,不必急于一时),以防分心从而破坏了对了解windows机制和程序有生到死过程的连贯性,请记住我们的目的  ——对windows机制和程序有生到死过程宏观和整体了解,其他是浮云,哈哈。

先来上一段代码——请别害怕

Cpp代码
1.  #include <windows.h>  
2.  LRESULT CALLBACK WinSunProc(  
3.  HWND hwnd,      // handle to window  
4.  UINT uMsg,      // message identifier  
5.  WPARAM wParam,  // first message parameter  
6.  LPARAM lParam   // second message parameter  
7.  );  
8.  int WINAPI WinMain(  
9.  HINSTANCE hInstance,      // handle to current instance  
10. HINSTANCE hPrevInstance,  // handle to previous instance
11. LPSTR lpCmdLine,          // command line
12. int nCmdShow              // show state
13. )
14. {  
15. WNDCLASS wndcls;        //定义一个wndcls窗口类对象  
16. wndcls.cbClsExtra=0;        //类变量占用的存储空间  
17. wndcls.cbWndExtra=0;       //实例变量占用的存储空间  
18. wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);//指定窗口类画刷句柄  
19. wndcls.hCursor=LoadCursor(NULL,IDC_ARROW);   //指定窗口类光标句柄  
20. wndcls.hIcon=LoadIcon(NULL,IDI_APPLICATION);  //指定窗口类图标句柄  
21. wndcls.hInstance=hInstance;                       //包含窗口过程的程序的实例句柄  
22. wndcls.lpfnWndProc=WinSunProc;                 //指向窗口过程函数  
23. wndcls.lpszClassName="Hello World";              //指定窗口类名字  
24. wndcls.lpszMenuName=NULL;                    //指定菜单资源名字  
25. wndcls.style=CS_HREDRAW | CS_VREDRAW;      //指定窗口类型样式  
26. RegisterClass(&wndcls); //注册窗口  
27. HWND hwnd;          //定义句柄变量 
28. hwnd=CreateWindow    //创建窗口,返回系统为窗口分配的句柄  
29. ("Hello World",         //类名,指定该窗口所属的类  
30. "Hello World Program",  //窗口的名字,即在标题栏中显示的文本  
31. WS_OVERLAPPEDWINDOW, //该窗口的风格  
32. 0,                             //窗口左上角相对于屏幕左上角的初始X坐标  
33. 0,                             //窗口左上角相对于屏幕左上角的初始Y坐标  
34. 600,                       //窗口的宽度  
35. 400,                           //窗口的高度  
36. NULL,                        //一个子窗口的父窗口的句柄,或隶属窗口的拥有者窗口的句柄  
37. NULL,                        //菜单句柄  
38. hInstance,                  //创建窗口对象的应用程序的实例句柄  
39. NULL);                       //创建窗口时指定的额外参数 
40. ShowWindow(hwnd,SW_SHOWNORMAL); //显示窗口  
41. UpdateWindow(hwnd);//更新窗口  
42. MSG msg;  
43. while(GetMessage(&msg,NULL,0,0))  
44. {  
45. TranslateMessage(&msg);  
46. DispatchMessage(&msg);  
47. }  
48. return msg.wParam;  
49. }  
50. LRESULT CALLBACK WinSunProc(  
51. HWND hwnd,      // handle to window  
52. UINT uMsg,      // message identifier  
53. WPARAM wParam,  // first message parameter  
54. LPARAM lParam   // second message parameter  
55. )  
56. {  
57. switch(uMsg)  
58. {  
59. case WM_CREATE:  
60. MessageBox(hwnd,"Window Created","message",MB_OK);  
61. break;  
62. case WM_PAINT:  
63. HDC hDC;  
64. PAINTSTRUCT ps;  
65. hDC=BeginPaint(hwnd,&ps);  
66. TextOut(hDC,0,0,"Hello World!",strlen("Hello World!"));  
67. EndPaint(hwnd,&ps);  
68. break;  
69. case WM_DESTROY:  
70. PostQuitMessage(0);  
71. break;  
72. default:  
73. return DefWindowProc(hwnd,uMsg,wParam,lParam);  
74. }  
75. return 0;  
76. }  

1. #include <windows.h> 2. LRESULT CALLBACK WinSunProc( 3. HWND hwnd, // handle to window 4. UINT uMsg, // message identifier 5. WPARAM wParam, // first message parameter 6. LPARAM lParam // second message parameter 7. ); 8. int WINAPI WinMain( 9. HINSTANCE hInstance, // handle to current instance 10. HINSTANCE hPrevInstance, // handle to previous instance 11. LPSTR lpCmdLine, // command line 12. int nCmdShow // show state 13. ) 14. { 15. WNDCLASS wndcls; //定义一个wndcls窗口类对象 16. wndcls.cbClsExtra=0; //类变量占用的存储空间 17. wndcls.cbWndExtra=0; //实例变量占用的存储空间 18. wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);//指定窗口类画刷句柄 19. wndcls.hCursor=LoadCursor(NULL,IDC_ARROW); //指定窗口类光标句柄 20. wndcls.hIcon=LoadIcon(NULL,IDI_APPLICATION); //指定窗口类图标句柄 21. wndcls.hInstance=hInstance; //包含窗口过程的程序的实例句柄 22. wndcls.lpfnWndProc=WinSunProc; //指向窗口过程函数 23. wndcls.lpszClassName="Hello World"; //指定窗口类名字 24. wndcls.lpszMenuName=NULL; //指定菜单资源名字 25. wndcls.style=CS_HREDRAW | CS_VREDRAW; //指定窗口类型样式 26. RegisterClass(&wndcls); //注册窗口 27. HWND hwnd; //定义句柄变量 28. hwnd=CreateWindow //创建窗口,返回系统为窗口分配的句柄 29. ("Hello World", //类名,指定该窗口所属的类 30. "Hello World Program", //窗口的名字,即在标题栏中显示的文本 31. WS_OVERLAPPEDWINDOW, //该窗口的风格 32. 0, //窗口左上角相对于屏幕左上角的初始X坐标 33. 0, //窗口左上角相对于屏幕左上角的初始Y坐标 34. 600, //窗口的宽度 35. 400, //窗口的高度 36. NULL, //一个子窗口的父窗口的句柄,或隶属窗口的拥有者窗口的句柄 37. NULL, //菜单句柄 38. hInstance, //创建窗口对象的应用程序的实例句柄 39. NULL); //创建窗口时指定的额外参数 40. ShowWindow(hwnd,SW_SHOWNORMAL); //显示窗口 41. UpdateWindow(hwnd);//更新窗口 42. MSG msg; 43. while(GetMessage(&msg,NULL,0,0)) 44. { 45. TranslateMessage(&msg); 46. DispatchMessage(&msg); 47. } 48. return msg.wParam; 49. } 50. LRESULT CALLBACK WinSunProc( 51. HWND hwnd, // handle to window 52. UINT uMsg, // message identifier 53. WPARAM wParam, // first message parameter 54. LPARAM lParam // second message parameter 55. ) 56. { 57. switch(uMsg) 58. { 59. case WM_CREATE: 60. MessageBox(hwnd,"Window Created","message",MB_OK); 61. break; 62. case WM_PAINT: 63. HDC hDC; 64. PAINTSTRUCT ps; 65. hDC=BeginPaint(hwnd,&ps); 66. TextOut(hDC,0,0,"Hello World!",strlen("Hello World!")); 67. EndPaint(hwnd,&ps); 68. break; 69. case WM_DESTROY: 70. PostQuitMessage(0); 71. break; 72. default: 73. return DefWindowProc(hwnd,uMsg,wParam,lParam); 74. } 75. return 0; 76. }

在WindowsXP环境下打开VC6.0(虽然有点老了,但对我们来说功能够用了),从File菜单中选择New,在Nem对话框中,单击Project标签,选择Win32Application。输入Project Name与Location后点确定。在下一个出现的对话框选EmptyWorkspace,再按下Finish。进入项目后,再新建一个C++Sourse File,将以上代码贴上后,点击BuildExecute按钮后将出现一个提示框(如图),点击确定后,会出现一个窗口(如图)。

概念解释

窗口是屏幕上与一个应用程序相关的矩形区域,它是用户与产生该窗口的应用程序之间的可视界面,他接收用户的输入,并以文本或图形的格式显示输出内容。对应用程序来说,窗口是应用程序控制下的屏幕上的一个矩形区域,应用程序创建并控制窗口的所有方面。当用户启动一个应用程序时,一个窗口就被创建。每当用户操作窗口中的对象时,程序就有所响应。

它一般由边框、标题栏、控制栏最小化图标、最大化图标、关闭图标水平滚动条、垂直滚动条、菜单栏和客户区构成。①

如常见的记事本就是一个很好的例子:

Windows程序运行的机制——一消息为基础,事件驱动之(引用侯捷老师《深入浅出MFC》)

概念解释:

事件与消息

事件由用户(操作电脑的人)触发且只能由用户触发(如用户按下了鼠标按钮,就产生一鼠标事件),操作系统能够感觉到由用户触发的事件,并将此事件转换为一个(特定的)消息发送到程序的消息队列中。

消息队列

消息被发送到队列中。“消息队列”是在消息的传输过程中保存消息的容器。消息队列管理器在将消息从它的源中继到它的目标时充当中间人。队列的主要目的是提供路由并保证消息的传递;如果发送消息时接收者不可用,消息队列会保留消息,直到可以成功地传递它。(来自百度百科)

Windows 程序的进行系依靠外部发生的事件来驱动。换句话说,程序不断等待(利用一个while 回路),等待任何可能的输入,然后做判断,然后再做适当的处理。上述的“输入”是由操作系统捕捉到之后,以消息形式(一种数据结构)进入程序之中。操作系统如何捕捉外围设备(如键盘和鼠标)所发生的事件呢?噢,USER 模块③(不懂先不管它)掌管各个外围的驱动程序,它们各有侦测回路。

如果把应用程序获得的各种“输入”分类,可以分为由硬件装置所产生的消息(如鼠标移动或键盘被按下),放在系统消息队列(system message queue)中,以及由Windows 系统或其它Windows 程序传送过来的消息,放在程序消息队列(application message queue)中。以应用程序的眼光来看,消息就是消息,来自哪里或放在哪里其实并没有太大区别,反正程序调用GetMessageAPI 就取得一个消息,程序的生命靠它来推动。所有的GUI(Graphical User Interface,图形用户界面) 系统,包括UNIX的X Window 以及OS/2 的Presentation Manager,都像这样,是以消息为基础的事件驱动系统。

可想而知,每一个Windows 程序都应该有一个回路如下(先熟悉一下即可):

MSG msg;

while(GetMessage(&msg, NULL, NULL, NULL)) {

TranslateMessage(&msg);

DispatchMessage(&msg);

}

// 以上出现的函数都是Windows API 函数

仅了解这个while循环有可以不断处理消息的作用即可。

Windows程序生与死——开始分析代码了!

不要被上面的代码行数吓坏了,对就是这么多行才产生一个窗口,没办法微软就是这么规定的,这个简简单单的窗口可以说是麻雀虽小,五脏俱全。但是几乎所有的windows程序都是有它为骨架扩展而来的,弄懂它你就会了一半的windows基本编程,剩下的工作顶多就是学学函数,填充一下它罢了。

一个程序的一生要经历出生、运行、死亡三个阶段,且听我慢慢道来……

出生:

正如在C程序中的进入点是函数main一样,Windows程序的进入点是WinMain,总是像这样出现:见行8 (再强调一下,只讲函数作用,具体用法参数含义后面讲)

引用孙鑫老师的精彩讲解

“创建一个完整的窗口,需要经过下面几个操作步骤:

设计一个窗口类;

注册窗口类;

创建窗口;

显示及更新窗口。

(请先记住这个顺序,先不要问为什么这样)

1.设计一个窗口类

一个完整的窗口具有许多特征,包括光标(鼠标进入该窗口时的形状)、图标、背景色等。窗口的创建过程类似于汽车的制造过程。我们在生产一个型号的汽车之前,首先要对该型号的汽车进行设计,在图纸上画出汽车的结构图,设计各个零部件,同时还要给该型号的汽车取一个响亮的名字,例如“奥迪A6”。在完成设计后,就可以按照“奥迪A6”这个型号生产汽车了。

类似地,在创建一个窗口前,也必须对该类型的窗口进行设计,指定窗口的特征。当

然,在我们设计一个窗口时,不像汽车的设计这么复杂,因为Windows 已经为我们定义好

了一个窗口所应具有的基本属性,我们只需要像考试时做填空题一样,将需要我们填充的部分填写完整,一种窗口就设计好了。(精彩的比喻)”

行15-行25:定义一个wndcls窗口类对象,并填充它。见代码注释(遇到新概念或看不懂先跳过,以后详细讲,下同)

2.注册窗口类

在设计完汽车后,需要报经国家有关部门审批,批准后才能生产这种类型的汽车。同

样地,设计完窗口类(WNDCLASS)后,需要调用RegisterClass 函数对其进行注册,注

册成功后,才可以创建该类型的窗口。”

行26:注册窗口

3.创建窗口——步骤3

设计好窗口类并且将其成功注册之后,就可以用CreateWindow 函数产生这种类型的

窗口了。”

行27-行29:创建窗口(遇到新概念或看不懂先跳过,以后详细讲)

4.显示及更新窗口

(1)显示窗口

窗口创建之后,我们要让它显示出来,这就跟汽车生产出来后要推向市场一样。调用

函数ShowWindow 来显示窗口。

(2)更新窗口

在调用ShowWindow 函数之后,我们紧接着调用UpdateWindow 来刷新窗口,就好像

我们买了新房子,需要装修一下。”

行41、41:显示及更新窗口

运行:

请回顾上回“windows程序运行机制——一消息为基础,以事件驱动之”,程序由一系列复杂的过程创建出来显示在屏幕上后,程序就时刻在等待消息,然后处理消息,这就是它“活着”。

程序是如何等待消息的呢,又是怎样处理的呢?请看代码,我们就来到了while消息循环

见行43-49 (只大致知道函数作用即可,现在不必深究其原理和用法)

函数GetMessage可以从消息队列中检索出与此应用程序窗口有关连的消息(一般情况,函数返回非零值让循环一直进行,什么时候函数返回零,消息循环结束,我们后面讲),并将消息的具体内容存于具有MSG类型的一个变量中(即msg,MSG类型后面讲),然后交由函数TranslateMessage对该消息进行翻译(翻译后面讲),紧接着,函数DispatchMessage将消息发送到适当的“对象”处理。

while消息循环如此往复进行,程序就能“活着”,不断进行等待消息、处理消息。

关于这个神秘的“对象”叫做窗口过程,它是一个函数(即行50-76,行2-7是此函数的声明),用来处理消息。你仔细观察你会发现这个函数的主体就是switch选择语句,那他选择的WM_CREATE,WM_PAINT,WM_DESTROY这又是什么呢,或许你已经猜到了,这些就是要特意处理的消息,如果传进来的消息没有响应它的case语段,那就一律交由default语段处理(看来它是必不可少的)。仿佛windows一切神秘的面纱已经渐渐地被我们掀开了!一个windows程序原来是这样这样的:它首先要被创建并显示在桌面上,这要经过设计一个窗口类、注册窗口类、创建窗口、显示及更新窗口等过程,你想要它有什么功能,就要在窗口过程函数switch选择语句中特意加一case语段来处理与你这功能相关的消息,对于不相关的消息一率交由default语段处理。可以这样说很多应用程序之所以不同,区别就在于其窗口过程的不同。至于while消息循环,这是固定的写法,我们只要这么写,具体消息的路由都是windows系统自动完成的,我们不用操心。

死亡:

讲到此或许读者应该可以推断出一点有关程序死亡的一点信息了:窗口程序要“死亡”肯定是要窗口函数收到某种消息并响应,让窗口销毁,同时还要结束while消息循环。(就先了解到这儿,下回再深入)

这次就先讲到这了,希望读者对windows程序的“一生”和它的运行机制有那么一点印象,能以宏观的角度看待它,那我就能感到心满意足了。这一回大家主要是理解,下一回我将详细讲代码中函数的具体用法和相关细节,需要大家多记忆。好了,大家后会有期。

① 说一下大家可能不熟悉的:

控制框是每个窗口左上方的小图片,每个应用程序都使用它。在控制图标上单击鼠标键会使Windows显示系统菜单。系统菜单它提供了诸如还原、移动、大小、最小化、最大化以及关闭这样的标准操作。

通常客户区占据了窗口最大的部分(即记事本中可以写字的区域)。这是应用程序的基本输出区域。应当由应用程序来复杂管理客户区。另外,应用程序可以输出到客户区。

② 补充:

我们通常说:“某一件事发生了”和“向什么发送某一个消息”。比如在桌面上单击鼠标时,某一件事发生了,Windows首先知道这件事的发生,然后使用函数SendMessage向桌面发送一个消息,证明有某件事发生了。这就是“事件驱动、消息处理”的原理。

事件是一个动作——用户触发的动作。 消息是一个信息——传递给系统的信息。这里强调的是: 可以说“用户触发了一个事件”,而不能说“用户触发了一个消息”。 用户只能触发事件,而事件只能由用户触发。 一个事件产生后,将被操作系统转换为一个消息,所以一个消息可能是由一个事件转换而来(或者由操作系统产生)。 一个消息可能会产生另一个消息,但一个消息决不能产生一个事件——时间只能由用户触发。
总结(事件:消息的来源) 事件:只能由用户通过外设的输入产生。 消息:(产生消息的来源有三个) (1) 由操作系统产生。 (2) 由用户触发的事件转换而来。 (3) 由另一个消息产生。

以上援引自《事件与消息的区别》

Windows的消息可分为四种类型:   

(1)输入消息:对键盘和鼠标输入作反应。这类输入消息首先放在系统消息队列中,然后Windows将它们送入应用程序的消息队列,使消息得到处理。   

(2)控制消息:用来与Windows的特殊控制对象,例如,对话框、列表框、按钮等进行双向通信。这类消息一般不通过应用程序的消息队列,而是直接发送到控制对象上。  

(3)系统消息:对程式化的事件或系统时钟中断作出反应。有些系统消息,例如大部分DDE消息(程序间进行动态数据交换时所使用的消息)要通过Windows的系统消息队列。而有些系统消息,例如窗口的创建及删除等消息直接送入应用程序的消息队列。   

(4)用户消息:这些消息是程序员创建的,通常,这些消息只从应用程序的某一部分进入到该应用程序的另一部分而被处理,不会离开应用程序。用户消息经常用来处理选单操作:一个用户消息与选单中的一选项相对应,当它在应用程序队列中出现时被处理。

模块   在Windows中,术语“模块”一般是指任何能被装入内存中运行的可执行代码和数据的集合。更明确地讲,模块指的就是一个.EXE文件(又称为应用程序模块),或一个动态链接库(DLL — Dynamic Linking Library,又被称为动态链接库模块或DLL模块),或一个设备驱动程序,也可能是一个程序包含的能被另一个程序存取的数据资源。模块一词也被用于特指自包含的一段程序。例如,一个可单独编译的源文件,或该源文件被编译器处理之后所生成的目标程序。当制作一个程序时,模块一词用于指被连接在一起的许多模块中的某个模块。   Windows本身由几个相关的模块组成,Windows API函数就是在Windows启动时装入内存中的几个动态链接库模块实现的。其中的三个主要模块是USER.EXE(用于窗口管理等)、KERNEL.EXE(用于内存管理的多任务调度)和GDI.EXE(图形设备接口,用于图形输出等)。

注:如未另注明,概念解释均来自《Windows编程基础 --概述》一文。

文中很多内容都引自《Windows编程基础 --概述》《深入浅出MFC》《VC++深入详解》,在此特向这三位作者致敬!

转载于:https://www.cnblogs.com/xiaogui9527/p/3222530.html

Windows编程 Windows程序的生与死(上)相关推荐

  1. Windows编程入门程序详解

    Windows编程入门程序详解 1.     程序 /************************************************************************* ...

  2. Windows编程—Windows驱动中定时器的使用

    文章目录 Windows编程-Windows驱动中定时器的使用 前言 代码 简单版 升级版 程序效果 Windows编程-Windows驱动中定时器的使用 前言 定时器操作是应用编程中非常常见的操作, ...

  3. Windows编程 第四回 Windows程序的生与死(下)

    致歉 很抱歉,读者看到的这篇文章将是我写的最没什么条理的一篇了,由于这一块儿内容是所有Windows程序的核心与基础,所以我分了三回来写.我想讲 得既易懂有又丰富,无奈本人才疏学浅,每每一提笔就要查很 ...

  4. Windows编程 Windows程序的生与死(下)

    再谈程序之"死" 记得在第二回中我对程序的"死"只是一句话带过,因为我还没有铺垫好,好了现在我们可以详细的分析一下这个过程了. 这还要从while消息循环说起, ...

  5. Windows编程—Windows驱动开发环境搭建

    文章目录 前言 步骤 步骤一 步骤二 步骤三 连接测试 步骤四 步骤五 总结 前言 作为一个编写Windows程序的开发人员,对Windows驱动开发 并非必需要掌握,但是掌握 Windows驱动开发 ...

  6. Windows程序的生与死

    Windows程序分为"程序代码"和"UI资源"两大部分最后以RC编译器整合为一个完整的EXE档案. "以消息为基础,以事件驱动(message ba ...

  7. Windows 程序的生与死----FROM 侯俊杰

    个人感觉比孙鑫讲的要简单,孙鑫讲的有点多了,理解不如候俊杰讲的~~~ 1. 程序初始化过程中调用CreateWindow,为程序建立了一个窗口,做为程序的萤幕舞台.CreateWindow 产生窗口之 ...

  8. C/C++:Windows编程—Inline Hook内联钩子(上)

    前言 先介绍下Windows中的Hook技术.Hook是Windows中提供的一种用以替换DOS下"中断"的系统机制,中文译为"挂钩"或"钩子&quo ...

  9. Windows编程—控制面板程序显示信息修改(程序图标、名称、链接等)

    文章目录 介绍 修改方法 介绍 笔者之前用inno setup打包发现控制面板显示的程序 没有启动程序的图标信息,所以顺带研究了一下控制面板上程序信息的显示.新手看了应该有用. 我们在 控制面板\程序 ...

  10. C/C++:Windows编程—Windows RPC 传递自定义数据类型、自定义数据类型数组、指针数组

    前言 该篇博文不是讲Windows rpc入门的.是笔者在实际使用Windows RPC时 所遇到的问题,以及解决方法. 笔者有这样的需求,需要从RPC Server获取大量数据,而且该数据是动态分配 ...

最新文章

  1. 公司用的 MySQL 团队开发规范,非常详细,
  2. 没有会员wps合并多个sheet_WPS「合并文档」功能,如何“唰”一下把多个文档合并到一起?...
  3. ubuntu中make头文件找不到_和平精英:游戏中找不到人怎么办?这些技巧帮你练出“火眼金睛”...
  4. Android之JSON处理器FastJson
  5. 产品经理如何做好信息架构
  6. php判断是不是纯汉字,php判断输入是否是纯数字,英文,汉字的方法
  7. pythonsparkfilter_python中的map、filter、reduce函数
  8. 结构化数据传输协议xml、json、protobuf比较
  9. 【优化算法】供需优化算法(SDO)【含Matlab源码 1804期】
  10. 运维系统 联想服务器,联想IT综合运维平台解决方案.pdf
  11. GIS地理空间数据免费获取
  12. dnf脚本是php,dnf自动搬砖脚本教程autojs在使用
  13. 信息系统项目管理师(2022年) —— 第 1 章 信息化和信息系统
  14. Vscode tab键使用
  15. 继续惨...555555555
  16. AI上推荐 之 MIND(动态路由与胶囊网络的奇光异彩)
  17. 介绍两个测试网页打开速度的网站
  18. P3918 [国家集训队]特技飞行
  19. 索爱j10 java,张崇:索爱J10怎么样呢?
  20. 关于最新笔记本机型预装win8如何更换为win7的解决办法

热门文章

  1. 复制计算机软件,一键复制粘贴工具
  2. 外卖优惠券cps系统每日领团饿了么外卖券CPS系统公众号小程序源码
  3. Unity 打图集Atlas
  4. speedoffice(PPT)怎么将背景设置为渐变背景
  5. 数字逻辑电路 逻辑运算 与、或、非、与非、或非、与或非、异或、同或 二进制运算技巧
  6. Java小程序--多彩时钟表盘的制作
  7. NMOS和PMOS的电路符号记忆方法
  8. write-through与write-back的区别
  9. python - 啃书 第八章 正则表达式
  10. 文件后缀名obju为什么打不开_obj是什么文件格式,obj扩展名文件如何打开?