请教MFC制作常规DLL的过程

请教MFC制作常规DLL的过程,第1张

找了一个,讲得还可以:

一般的,在介绍Windows编程的书中讲述DLL的有关知识较多,而介绍MFC的书则比较少地提到。即使使用MFC来编写动态链接库,对于初步接触DLL的程序员来说,了解DLL的背景知识是必要的。另外,MFC提供了新的手段来帮助编写DLL程序。所以,本节先简洁的介绍有关概念。

DLL的背景知识

静态链接和动态链接

当前链接的目标代码(obj)如果引用了一个函数却没有定义它,链接程序可能通过两种途径来解决这种从外部对该函数的引用:

静态链接

链接程序搜索一个或者多个库文件(标准库lib),直到在某个库中找到了含有所引用函数的对象模块,然后链接程序把这个对象模块拷贝到结果可执行文件(exe)中。链接程序维护对该函数的所有引用,使它们指向该程序中现在含有该函数拷贝的地方。

动态链接

链接程序也是搜索一个或者多个库文件(输入库lib),当在某个库中找到了所引用函数的输入记录时,便把输入记录拷贝到结果可执行文件中,产生一次对该函数的动态链接。这里,输入记录不包含函数的代码或者数据,而是指定一个包含该函数代码以及该函数的顺序号或函数名的动态链接库。

当程序运行时,Windows装入程序,并寻找文件中出现的任意动态链接。对于每个动态链接,Windows装入指定的DLL并且把它映射到调用进程的虚拟地址空间(如果没有映射的话)。因此,调用和目标函数之间的实际链接不是在链接应用程序时一次完成的(静态),相反,是运行该程序时由Windows完成的(动态)。

这种动态链接称为加载时动态链接。还有一种动态链接方式下面会谈到。

动态链接的方法

链接动态链接库里的函数的方法如下:

加载时动态链接(Load_time dynamic linking)

如上所述。Windows搜索要装入的DLL时,按以下顺序:

应用程序所在目录→当前目录→Windows SYSTEM目录→Windows目录→PATH环境变量指定的路径。

运行时动态链接(Run_time dynamic linking)

程序员使用LoadLibrary把DLL装入内存并且映射DLL到调用进程的虚拟地址空间(如果已经作了映射,则增加DLL的引用计数)。首先,LoadLibrary搜索DLL,搜索顺序如同加载时动态链接一样。然后,使用GetProcessAddress得到DLL中输出函数的地址,并调用它。最后,使用FreeLibrary减少DLL的引用计数,当引用计数为0时,把DLL模块从当前进程的虚拟空间移走。

输入库(lib):

输入库以lib为扩展名,格式是COFF(Common object file format)。COFF标准库(静态链接库)的扩展名也是lib。COFF格式的文件可以用dumpbin来查看。

输入库包含了DLL中的输出函数或者输出数据的动态链接信息。当使用MFC创建DLL程序时,会生成输入库(lib)和动态链接库(dll)。

输出文件(exp)

输出文件以exp为扩展名,包含了输出的函数和数据的信息,链接程序使用它来创建DLL动态链接库。

映像文件(map)

映像文件以map为扩展名,包含了如下信息:

模块名、时间戳、组列表(每一组包含了形式如section::offset的起始地址,长度、组名、类名)、公共符号列表(形式如section::offset的地址,符号名,虚拟地址flat address,定义符号的obj文件)、入口点如section::offset、fixup列表。

libexe工具

它可以用来创建输入库和输出文件。通常,不用使用libexe,如果工程目标是创建DLL程序,链接程序会完成输入库的创建。

更详细的信息可以参见MFC使用手册和文档。

链接规范(Linkage Specification )

这是指链接采用不同编程语言写的函数(Function)或者过程(Procedure)的链接协议。MFC所支持的链接规范是“C”和“C++”,缺省的是“C++”规范,如果要声明一个“C”链接的函数或者变量,则一般采用如下语法:

#if defined(__cplusplus)

extern "C"

{

#endif

//函数声明(function declarations)

//变量声明(variables declarations)

#if defined(__cplusplus)

}

#endif

所有的C标准头文件都是用如上语法声明的,这样它们在C++环境下可以使用。

修饰名(Decoration name)

“C”或者“C++”函数在内部(编译和链接)通过修饰名识别。修饰名是编译器在编译函数定义或者原型时生成的字符串。有些情况下使用函数的修饰名是必要的,如在模块定义文件里头指定输出“C++”重载函数、构造函数、析构函数,又如在汇编代码里调用“C””或“C++”函数等。

修饰名由函数名、类名、调用约定、返回类型、参数等共同决定。

调用约定

调用约定(Calling convention)决定以下内容:函数参数的压栈顺序,由调用者还是被调用者把参数弹出栈,以及产生函数修饰名的方法。MFC支持以下调用约定:

_cdecl

按从右至左的顺序压参数入栈,由调用者把参数弹出栈。对于“C”函数或者变量,修饰名是在函数名前加下划线。对于“C++”函数,有所不同。

如函数void test(void)的修饰名是_test;对于不属于一个类的“C++”全局函数,修饰名是test@@ZAXXZ。

这是MFC缺省调用约定。由于是调用者负责把参数弹出栈,所以可以给函数定义个数不定的参数,如printf函数。

_stdcall

按从右至左的顺序压参数入栈,由被调用者把参数弹出栈。对于“C”函数或者变量,修饰名以下划线为前缀,然后是函数名,然后是符号“@”及参数的字节数,如函数int func(int a, double b)的修饰名是_func@12。对于“C++”函数,则有所不同。

所有的Win32 API函数都遵循该约定。

_fastcall

头两个DWORD类型或者占更少字节的参数被放入ECX和EDX寄存器,其他剩下的参数按从右到左的顺序压入栈。由被调用者把参数弹出栈,对于“C”函数或者变量,修饰名以“@”为前缀,然后是函数名,接着是符号“@”及参数的字节数,如函数int func(int a, double b)的修饰名是@func@12。对于“C++”函数,有所不同。

未来的编译器可能使用不同的寄存器来存放参数。

thiscall

仅仅应用于“C++”成员函数。this指针存放于CX寄存器,参数从右到左压栈。thiscall不是关键词,因此不能被程序员指定。

naked call

采用1-4的调用约定时,如果必要的话,进入函数时编译器会产生代码来保存ESI,EDI,EBX,EBP寄存器,退出函数时则产生代码恢复这些寄存器的内容。naked call不产生这样的代码。

naked call不是类型修饰符,故必须和_declspec共同使用,如下:

__declspec( naked ) int func( formal_parameters )

{

// Function body

}

过时的调用约定

原来的一些调用约定可以不再使用。它们被定义成调用约定_stdcall或者_cdecl。例如:

#define CALLBACK __stdcall

#define WINAPI __stdcall

#define WINAPIV __cdecl

#define APIENTRY WINAPI

#define APIPRIVATE __stdcall

#define PASCAL __stdcall

表7-1显示了一个函数在几种调用约定下的修饰名(表中的“C++”函数指的是“C++”全局函数,不是成员函数),函数原型是void CALLTYPE test(void),CALLTYPE可以是_cdecl、_fastcall、_stdcall。

表7-1 不同调用约定下的修饰名

调用约定

extern “C”或C文件

cpp, cxx或/TP编译开关

_cdecl

_test

test@@ZAXXZ

_fastcall

@test@0

test@@YIXXZ

_stdcall

_test@0

test@@YGXXZ

MFC的DLL应用程序的类型

静态链接到MFC的规则DLL应用程序

该类DLL应用程序里头的输出函数可以被任意Win32程序使用,包括使用MFC的应用程序。输入函数有如下形式:

extern "C" EXPORT YourExportedFunction( );

如果没有extern “C”修饰,输出函数仅仅能从C++代码中调用。

DLL应用程序从CWinApp派生,但没有消息循环。

动态链接到MFC的规则DLL应用程序

该类DLL应用程序里头的输出函数可以被任意Win32程序使用,包括使用MFC的应用程序。但是,所有从DLL输出的函数应该以如下语句开始:

AFX_MANAGE_STATE(AfxGetStaticModuleState( ))

此语句用来正确地切换MFC模块状态。关于MFC的模块状态,后面第9章有详细的讨论。

其他方面同静态链接到MFC的规则DLL应用程序。

扩展DLL应用程序

该类DLL应用程序动态链接到MFC,它输出的函数仅可以被使用MFC且动态链接到MFC的应用程序使用。和规则DLL相比,有以下不同:

它没有一个从CWinApp派生的对象;

它必须有一个DllMain函数;

DllMain调用AfxInitExtensionModule函数,必须检查该函数的返回值,如果返回0,DllMmain也返回0;

如果它希望输出CRuntimeClass类型的对象或者资源(Resources),则需要提供一个初始化函数来创建一个CDynLinkLibrary对象。并且,有必要把初始化函数输出。

使用扩展DLL的MFC应用程序必须有一个从CWinApp派生的类,而且,一般在InitInstance里调用扩展DLL的初始化函数。

为什么要这样做和具体的代码形式,将在后面942节说明。

MFC类库也是以DLL的形式提供的。通常所说的动态链接到MFC 的DLL,指的就是实现MFC核心功能的MFCXXDLL或者MFCXXDDLL(XX是版本号,XXD表示调试版)。至于提供OLE(MFCOXXDDLL或者MFCOXX0DLL)和NET(MFCNXXDDLL或者MFCNXXDLL)服务的DLL就是动态链接到MFC核心DLL的扩展DLL。

其实,MFCXXDLL可以认为是扩展DLL的一个特例,因为它也具备扩展DLL的上述特点。

DLL的几点说明

DLL应用程序的入口点是DllMain。

对程序员来说,DLL应用程序的入口点是DllMain。

DllMain负责初始化(Initialization)和结束(Termination)工作,每当一个新的进程或者该进程的新的线程访问DLL时,或者访问DLL的每一个进程或者线程不再使用DLL或者结束时,都会调用DllMain。但是,使用TerminateProcess或TerminateThread结束进程或者线程,不会调用DllMain。

DllMain的函数原型符合DllEntryPoint的要求,有如下结构:

BOOL WINAPI DllMain (HANDLE hInst,

ULONG ul_reason_for_call,LPVOID lpReserved)

{

switch( ul_reason_for_call ) {

case DLL_PROCESS_ATTACH:

case DLL_THREAD_ATTACH:

case DLL_THREAD_DETACH:

case DLL_PROCESS_DETACH:

}

return TRUE;

}

其中:

参数1是模块句柄;

参数2是指调用DllMain的类别,四种取值:新的进程要访问DLL;新的线程要访问DLL;一个进程不再使用DLL(Detach from DLL);一个线程不再使用DLL(Detach from DLL)。

参数3保留。

如果程序员不指定DllMain,则编译器使用它自己的DllMain,该函数仅仅返回TRUE。

规则DLL应用程序使用了MFC的DllMain,它将调用DLL程序的应用程序对象(从CWinApp派生)的InitInstance函数和ExitInstance函数。

扩展DLL必须实现自己的DllMain。

_DllMainCRTStartup

为了使用“C”运行库(CRT,C Run time Library)的DLL版本(多线程),一个DLL应用程序必须指定_DllMainCRTStartup为入口函数,DLL的初始化函数必须是DllMain。

_DllMainCRTStartup完成以下任务:当进程或线程捆绑(Attach)到DLL时为“C”运行时的数据(C Runtime Data)分配空间和初始化并且构造全局“C++”对象,当进程或者线程终止使用DLL(Detach)时,清理C Runtime Data并且销毁全局“C++”对象。它还调用DllMain和RawDllMain函数。

RawDllMain在DLL应用程序动态链接到MFC DLL时被需要,但它是静态的链接到DLL应用程序的。在讲述状态管理时解释其原因。

DLL的函数和数据

DLL的函数分为两类:输出函数和内部函数。输出函数可以被其他模块调用,内部函数在定义它们的DLL程序内部使用。

虽然DLL可以输出数据,但一般的DLL程序的数据仅供内部使用。

DLL程序和调用其输出函数的程序的关系

DLL模块被映射到调用它的进程的虚拟地址空间。

DLL使用的内存从调用进程的虚拟地址空间分配,只能被该进程的线程所访问。

DLL的句柄可以被调用进程使用;调用进程的句柄可以被DLL使用。

DLL使用调用进程的栈。

DLL定义的全局变量可以被调用进程访问;DLL可以访问调用进程的全局数据。使用同一DLL的每一个进程都有自己的DLL全局变量实例。如果多个线程并发访问同一变量,则需要使用同步机制;对一个DLL的变量,如果希望每个使用DLL的线程都有自己的值,则应该使用线程局部存储(TLS,Thread Local Strorage)。

输出函数的方法

传统的方法

在模块定义文件的EXPORT部分指定要输入的函数或者变量。语法格式如下:

entryname[=internalname] [@ordinal[NONAME]] [DATA] [PRIVATE]

其中:

entryname是输出的函数或者数据被引用的名称;

internalname同entryname;

@ordinal表示在输出表中的顺序号(index);

NONAME仅仅在按顺序号输出时被使用(不使用entryname);

DATA表示输出的是数据项,使用DLL输出数据的程序必须声明该数据项为_declspec(dllimport)。

上述各项中,只有entryname项是必须的,其他可以省略。

对于“C”函数来说,entryname可以等同于函数名;但是对“C++”函数(成员函数、非成员函数)来说,entryname是修饰名。可以从map映像文件中得到要输出函数的修饰名,或者使用DUMPBIN /SYMBOLS得到,然后把它们写在def文件的输出模块。DUMPBIN是VC提供的一个工具。

如果要输出一个“C++”类,则把要输出的数据和成员的修饰名都写入def模块定义文件。

在命令行输出

对链接程序LINK指定/EXPORT命令行参数,输出有关函数。

使用MFC提供的修饰符号_declspec(dllexport)

在要输出的函数、类、数据的声明前加上_declspec(dllexport)的修饰符,表示输出。MFC提供了一些宏,就有这样的作用,如表7-2所示。

表7-2 MFC定义的输入输出修饰符

宏名称

宏内容

AFX_CLASS_IMPORT

__declspec(dllexport)

AFX_API_IMPORT

__declspec(dllexport)

AFX_DATA_IMPORT

__declspec(dllexport)

AFX_CLASS_EXPORT

__declspec(dllexport)

AFX_API_EXPORT

__declspec(dllexport)

AFX_DATA_EXPORT

__declspec(dllexport)

AFX_EXT_CLASS

#ifdef _AFXEXT

AFX_CLASS_EXPORT

#else

AFX_CLASS_IMPORT

AFX_EXT_API

#ifdef _AFXEXT

AFX_API_EXPORT

#else

AFX_API_IMPORT

AFX_EXT_DATA

#ifdef _AFXEXT

AFX_DATA_EXPORT

#else

AFX_DATA_IMPORT

AFX_EXT_DATADEF

像AFX_EXT_CLASS这样的宏,如果用于DLL应用程序的实现中,则表示输出(因为_AFX_EXT被定义,通常是在编译器的标识参数中指定该选项/D_AFX_EXT);如果用于使用DLL的应用程序中,则表示输入(_AFX_EXT没有定义)。

要输出整个的类,对类使用_declspec(_dllexpot);要输出类的成员函数,则对该函数使用_declspec(_dllexport)。如:

class AFX_EXT_CLASS CTextDoc : public CDocument

{

}

extern "C" AFX_EXT_API void WINAPI InitMYDLL();

这几种方法中,最好采用第三种,方便好用;其次是第一种,如果按顺序号输出,调用效率会高些;最次是第二种。

在“C++”下定义“C”函数,需要加extern “C”关键词。输出的“C”函数可以从“C”代码里调用。

1、建立工程:New -> Projects,选择Win32 MFC AppWizard(exe),并输入工程(counter)名字及设置好路径,点击OK,选择“Dialog based”,基于对话框,直接点finish。

2、将对话框进行简单的处理,把无关的按钮删掉,添加自己的按钮及Edit Box,如图2。

图2

3、对按钮及Edit Box进行属性设置,比如按钮1属性设置为“IDC_BUTTON_1”,2设置为IDC_BUTTON_2,一直类推。Edit Box不仅要设置ID(IDC_DISPLAY),还要设置相关连的成员变量,右键,选择ClasssWizard,在点击Add Variable,这里设置为double m_display。

4、对每个按钮添加消息处理函数,只需双击该按钮,按照提示点OK,就进入到了该函数入口处。

1设置void CCounterDlg::OnButton1();

2设置void CCounterDlg::OnButton2();

其他类推。

加 void CCounterDlg::OnButtonAdd();

减void CCounterDlg::OnButtonSub();

乘void CCounterDlg::OnButtonMult();

除void CCounterDlg::OnButtonDiv();

= void CCounterDlg::OnButtonEqual();

5、定义成员变量

int count;  //计数

BOOL dot_flg; //小数点标志

BOOL continue_flg;//没按运算符,是否一直连续按数字按钮标志

BOOL str_flag;//有没按运算符标志

CString str;//记录当前按的运算符

double result; //num1和num2运算的结果

double num1; //按运算符之前的第一个数

double num2; //按运算符之后的第二个数

6、定义成员函数,该函数主要是对按下的数字进行叠加,跟踪num1和num2:

double CCounterDlg::buttonDownNum(int numSize);

7、当按下之后数字要及时显示出来,需要用到:

UpdateData(FALSE);  //该函数是对Edit Box的内容进行更新,FALSE是有内部数成员的数据值更新到界面上,TRUE是从界面上更新到内部的数据成员上。

GetDlgItem(IDC_DISPLAY)->SetWindowText("小数点");//可以利用这个语句直接在Edit Box上显示内容“小数点”。只是提示自己也可以用这个来显示,程序中注释掉了。

看着你写给我的邮件,听着你传过来的那首《代价》,眼泪终究还是不争气地掉了下来。离人心,眼泪飞,相爱,却又要彼此伤害。爱得越深,伤得越深。如果我们从来没有相遇,从来不曾相爱过,那么就会少了一些伤心与遗憾。我们走到今天这一步,或许只能够说明我们有缘无分,情深缘浅吧。这世界有着太多的这样那样的限制与隐秘的禁忌,又有太多难以预测的变故和身不由己的离合。这个世上有一种感情叫无缘,不是不爱你,我只是认同无缘。有情人不一定都能够终成眷属。

爱一个人,就是全心全意且无条件地付出,而不是以爱名义下的占有。爱,是相互的包容,理解、体谅与善待。你的那些爱的承诺,那些爱的宣言,那些爱的独白,依然能够记起,依然很感动。你缺乏安全感,你深感疲惫,这些我都能够理解,可是你又是否想过我也缺乏这些呢?

爱情真的就像一道选择题,有些答案我们以为是对的,结果却是错的;有些答案我们清楚地知道是错的,所以远远避开,我们最终要选择的其实是最后一个答案,这个答案清清楚楚地告诉我们:以上答案都不对。其实,你给我出的选择题我都能够理解,只是很难接受那个以承诺作为付出,或者决定我是否拥有爱情的谈判条件。真的,你所做的这一切都错了,而且大错特错了。你之所以有此行为,如今我真的不想也不愿意说你是多么多么地自私,也不想说难道这就是你爱我的一种方式。不管你的这番行为是你深思熟虑近一周的结果,还是短暂的冲动,不过这真的直接影响到了我们的情感,也伤害了我的心,还给我的家庭成员留下了不好的印象。你到底是自毁了形象,毁坏了我们的这段情,抑或还是我的原因呢?我真的迷糊了,似乎也不想去弄明白了。或许这就是爱的代价吧,或许这一切都是命中注定的吧!

如果说分手最终是我提出的,倒不如说分手的前因是你之前的种种困惑与怀疑。关于分手,之前我会说,我只是在尊重你的决定,尊重自己的决定。可是这几天我真的心平气和地想了许多。我们之间到底出了什么问题,是不是还有其他一些原因呢?

在我眼里,我一直相信着爱情,能够被你爱,是我的幸运,我能够有机会爱你,也是我的幸运。可是我们对彼此的爱不能够自私。不知道你是否仍然记得我们曾多次说过,假如我们能够最终走到一起,都不愿也不可能每天借助电话来问短问长,我们需要人陪伴,来生活。尽管我知道在爱的路上,一定会舍弃一些东西,可是我还是不愿意让你为了爱,为了我而放弃一些东西。你需要在一个合适的地方施展你的才能,发挥你的优势,去实现自我价值,因为我相信你终究会朝向你心之所向,实现心中的目标。我不能够给你或者我们的这份爱任何承诺,无论是口头的还是行动的,其实所有的承诺真的就像空气一般。我不知道我的未来是什么样子,我只知道,我一直在按照自己的步伐一个脚印一个脚印地在走,正如许多年前我曾写道:旋转的怡璇到底能够走多远所以对于你,我真的不能够太自私,我只能够放走属于我们俩的爱情,把我对你的那份爱藏在心中,也把你留给我的那份爱藏在心里。

如果这些都还不够的话,那就是我不能够让你活得太累,活得太没有安全感。就当我是一个非常俗气的人,就当我是一个非常现实的人,就当我是一个非常物质的人,就当我是一个对生活很挑剔的人,就当我是一个很自私自利的人,就当我是一个想当然地认为你无法满足我的要求的人,就当我只是一个给你不断提要求,带来麻烦、带来伤痛、带来眼泪的人。可是说了这么多,我仍旧不会说我讨厌自己,痛恨自己,因为我也曾给我们俩的日子带来过快乐,因为我一直在做自己,成全自己。

转眼间各奔天涯,天空飘过了两朵云啊,酸甜苦辣藏在我们各自的心间。多年以后的我们,都会有各自的他(她)。是的,没有人能够保证一切永远不再变了,没有人能够放得下心,可是我们还是要去追寻,去找个对我们各自更好的人。可是,我能够找得到吗?我真的不敢去想象。不过,你一定会找到那么一个人,她能够给你带来幸福,然后你深情地对她说:因为我错过了她,我才遇见了你。

小结:不管两个人是因为什么原因而分手,毕竟曾经的爱是真的,不要忘记了感谢她曾经对你所做的一切。

伤感情书 用歌名写的伤感情书

1、《当我遇上你》我就知道《遇上你是我的缘》,《第一次》有《心上人》的《感觉》是《甜蜜蜜》的,《无论如何》《我知道》我《就是喜欢你》,《如果只得一星期》我也会《抱紧你》说《一千遍我爱你》。如果《有人》《喜欢你》,我会和他《赌爱》,令他成为我的《手下败将》,我一定要他《非走不可》,因为《我是真的真的很爱你》,你是我心中的《天使》,我只想《安静》地《简单爱》着你。

2、虽然我《明白》在你心中《我不是一百分》,但也请你给我一次《机会》,就算你是一个平凡的《女生》,我也《心甘情愿》《一生一世只爱你一人》。因为《恋爱大过天》在这个《情人节》,我《期待》能和你《牵手》,看着《流星雨》,然后许下《一千零一个愿望》,向《少女的祈祷》《真心真意》地说声《真的爱你》。

3、在我的心中,你是我《独一无二》的《情人》,也是《从头到尾》唯一的一个,我《相信》你不会《离开》我,因为你不像那些《坏女人》一样会《移情别恋》。

4、《说真的》我对你已《神魂颠倒》了,《只要为你活一天》就算死我也《愿意》《走到底》,《爱上你》《我愿意》不要《自由》,只因《我比想像中爱你》。

5、那天你对我说《分手吧》就《挂线了》。你的话《无形》地刺得我好《心痛》,《为什么》会这样。那天,我的心里下了一场《认真的雪》,抬起头看夜色却看到了《北极星的眼泪》,不知道《天亮以后》该怎么办,为了你,我想《断了爱情的念头》,可我《爱》你,我希望《今生你做伴》。

6、还记得《那一年,那一天》吗?你对我许下了《你的承诺》,《一个人的冬天》真的好《孤单》,你的心像《红色石头》一样有热情的血液和石头的《冰冷》,《突然好想你》。

7、《被遗忘的爱》你会不会《拾起》,我好想说一句《I MISS YOU 》,其实我《爱你胜过爱我自己》,对你《不得不爱》,分手的《那一夜》我哭了,《别说我的眼泪你无所谓》,你就是我的《宝贝》我会《永远永远》爱你。

8、和你在一起的感觉像吃了《棉花糖》似得《甜甜的》,《我对天空说》《做我老婆好不好》让它转达给你,你就是我的《专属天使》,我想和你做对儿《幸福恋人》,《好好爱我》好吗?

9、《没有你的日子我真的好孤单》,《舍不得》让你离开我,我不能《错了再错》,我要追你回来,让你在我《左边》陪我,找回我们《遗失的美好》。想你时会《缺氧》,因为我《超喜欢你》《只对你有感觉》。为了你我愿意折断我《天使的翅膀》放弃整个《天堂》,只因为你是我的《唯一》。最后送给你《九千九百九十九朵玫瑰》向你说:《我爱你》!终于写完了,累死了,不过为了你,值得!这就是《九十九首歌》代表的爱情。

10、《我不想说》《很爱很爱你》,可我《好想好想》《微微地告知你》,《遇见》你是《非同寻常》的《奇观》。在这《似水年华》里,我们《边走边唱》,一起《遥望》《来日》,《祷告》《美梦成真》。由于《生如夏花》般残暴,《每天》都是那么《神奇》、《透明》跟《新颖》,所以我们充斥了《勇气》,将《爱随身携带》。兴许《十年》之后,在《明天的明天的明天》,你我早已成为《有故事的人》,可不论你在《远方》《怎么Happy》,也别忘了咱们《曾经》《风雨无阻》地《奔驰》在《那么自豪》的路上以及那些《一起刻苦的幸福》。

12、我给你的《爱在西元前》,深埋在那个俏丽的《机密花园》。带上《荣幸舆图》和《快乐指南》针《向快乐动身》吧。《信任自己》,《没有什么不可以》。你一定会乘着《幸福》号《飞船》《一路顺风》地下降在《爱情诺曼底》,走入《美丽新世界》,找到那片《白桦林》。在那里,我《为你》种下的《忘忧草》早已结满了《盛夏的果实》《相思成灾》的《红豆》,里面有《一千零一个欲望》送给我《梦寐以求》的你:愿你占有《最美》的《彩虹》;愿你领有《十二种色彩》的《Colour fuldays》,愿你的《快乐老家》布满《爱》的《魔力》;愿你和《密切爱人》的《爱情一百年》都是《初恋般的滋味》,愿你的《Happybaby》《魅力无穷》《等等等等》。

13、《我的爱对你说》,《你是幸福的,我是快乐的》。我是真的《好想好好爱你》。《无论有多苦》,即便我《命中注定》要《一辈子的孤单》,也依然会《祝福》你,《好人毕生安全》。《假如有一天》,《我要找到你》,要《每天看到你》,而后告诉你,《我是真的真的很爱你》。在这个世上,你是我的《唯一》,《我只在乎你》,我会在这里《等你爱我》,让我们《永远在一起,好吗》?

14、这就是我对你的《表白》,《愿望》它像《当真的雪》一样,让你感觉到我的《真爱》,像《暖暖》的阳光一样,《把耳朵叫醒》。《那一夜》,你听,我的《寂寞在唱歌》,固然我明白《有一种爱叫做撒手》,但依然无法《忘却》《你的样子》。《爱就爱了》,可是《你必定要幸福》。直到《一千年当前》,我依然会《记得》,在《挪威的森林》,我们《最初的》像《彩虹的微笑》一样漂亮,《紫藤花》还在《绽开》。《六月的雨》落在身上,淋湿我《隐形的翅膀》。《如果这都不算爱》,我《那么爱你为什么》?《回来我的爱》,我早已为你筹备好了《九百九十九朵玫瑰》和《香水百合》,在《珊瑚海》的《蝴蝶泉边》等你。因为我们《说好不分别》,其实《爱很简单》,只有《终生有你》,所有的所有都《无所谓》。我们《举世无双》的《爱如空气》在世界的每个角落,《我要我们在一起》这就足够了。

15、《遇上你是我的缘》,可能,《意识你真好》,最近,《对你的思念老是特别深》,《没有像你》一样令我心动,我不想《说谎》、《瞒哄》、《我想我是真的爱上你了》,《我的眼里只有你》。虽然我说过,《我与你》,只能做特殊的《友人》,然而《在我心深处》,《始终只爱你》。我如许《生机》那是我《毛病的决择》。

小结:情书不是写小说也不是在秀文采,不需要多么优美华丽的句子,最能打动人的,往往是告诉他,你有多爱她。

黑客的伤感情书

HACK技术学的再好,

却无法入侵你的心,

服务器入侵的再多,

对你只有GUEST,

是我的DDOS造成了你的拒绝服务?

还是我的byshell再次被你查杀?

你总有防火墙 我始终停不掉

想提权 无奈JSp+MYSQL成为我们的障碍

找不到你的注入点 扫不到你的空口令

所有对我的回应都用3DES加密

你总是自定文件格式 我永远找不到你的入口点

忽略所有异常 却还是跟踪不到你的注册码

虽然我们是不同的对象,都有隐私的一面,

但我相信总有一天我会找到你的接口,

把我的最真给你看!

因为我是你的指针,

在茫茫内存的堆栈中, 永远指向你那片天空,不孜不倦!

我愿做你的内联,供你无限次的调用,直到海枯石烂!

我愿做你的引用,和你同进退共生死,一起经受考验!

只是我不愿苦苦地调试你的心情,最终沦为你的友元!

如今我们已被MFC封装--事事变迁!

如今我们已向COM走去--可想当年!

没任何奢求,只愿做你最后的Administrator

世上最伤感情书

------这世上,也许有很多人值得我们去爱,也有很多人爱着我们,但爱情,却不常发生。当爱情降临的时候,亲爱的,我却把她弄丢了 亲爱的雪儿:想这是最后一封给你的情书了,其实我们分手都已经两个月多23天了,连情书,都不算了,或者是我的怀念吧。

我其实是一个不太懂得爱的人,在压力面前,我不会缓解自己的情绪。记得

上次你回到我身边时,我给你留言说:以后不要轻易说分手,有问题一定要摆出来。可我终究没办法好好和你沟通,长久的压力,瞬间的冲动,说了分手。

你哭了太久,哭了太多天。那天晚上,你喝醉给我电话,我去看你了,你开门时,当你站在门口,看着我的眼神,让我心伤。我怎舍得如此让你伤心,我当时心疼的要死,我是多么爱你,我怎会舍得伤害你。可第二天,我拿胃药给你,

想分手都让自己关了心门,你的一个脾气,让我欲留又走,从此,无法回头。

我现在都还在自责,我都走不出这圈。曾经我们多么接近我们想要的幸福,为何还是就此打住。我是男人,我怎可以如此轻易被影响,而我怎可以因为你的一时情绪就说分手,而再没有沟通的勇气。我再看分手时,给你的那封e-mail,当时心情使然,可为何造化也如此弄人。

分手了,我不该再电话你了,可前两天,我想回来,我给你读一篇文章,又把你弄哭了。我其实最舍不得你哭的,可总事与愿违。你是孩子气的,可我却也任性。所以,缘起执手,缘灭离散,我只能安慰我自己。只是,两年的时间,太多的回忆,真的,没有一个幸福的结果,伤害了两个人的心。

亲爱的雪儿,最后一次这样叫你吧。再过几个月,是你生日了。我衷心希望你幸福,希望有人能更爱你,有个真正懂得爱你的人,在你身边。我不能再扰乱你的生活,不能再给你短信,我在心里祝福你吧,5月26日,你的生日,祝福你快乐,其实我一直没有忘记。

现在有几种方法,从远到近说:

1、直接用windows API,语法是C的;

2、使用MFC,他是对windows API进行类的封装,语法是C++;

3、使用QT,C++语法,图形化的,这我不太熟;

4、使用WPF,这个比较特殊,他是专门做应用程序界面的,做出来及其绚丽,但他的语法好像是C#,还有什么Frame框架,反正他的语法不是C++,但可以与C++做的后台程序进行交互,现在的趋势也是用他做界面,C#做前端事务,C++做后台程序。

如果你是用微软的编译器,在windows上运行,我建议你用MFC。

需要你注意的是,C++是门语言,直接学习MFC会对学习单纯的标准C++有巨大的阻碍作用,希望小心。

CBrush pOldBrush;

CBrush brush;

brushCreateSolidBrush(m_cFillColor);//这个时候,刷子已经选好了,想填充什么图形,画就可以了

m_pMemDC->Rectangle(rect);//画一个矩形填充

m_pMemDC->SelectObject(pOldBrush);

、问题描述:

该游戏可以由程序随机产生或由用户输入四个0到9之间的数字,且不重复。玩游戏者通过游戏提示输入八次来匹配上面所输入的数字。A表示位置正确且数字正确,B表示数字正确而位置不正确。

二、功能要求:

1、本游戏显示这样的菜单:

(1) 随机产生数据

(2) 用户输入数据

(3) 退出游戏

2、游戏成功与否都能返回主菜单

三、算法提示:

1、 数据结构:数组

2、 用简单的程序设计方法

四、测试数据:

测试数据: 3792

第一次输入: 1234

0A2B

第二次输入: 5678

0A1B

第三次输入: 0867

0A1B

第四次输入: 9786

1A1B

第五次输入: 1794

2A0B

第六次输入: 2793

2A2B

第七次输入: 3792

4A0B

游戏成功!!!

五、其它:

对该系统有兴趣的同学可以在实现系统基本功能后,完善系统的其它功能,如:破记录功能,若你所匹配的次数小于纪录保持者,则为破纪录。

①完成系统需求分析:包括系统设计目的与意义;系统功能需求;输入输出的要求。②完成系统概要设计:程序由哪些模块组成以及模块之间的层次结构、各模块的调用关系;每个模块的功能;课题涉及的数据结构和数据库结构;即要存储什么数据,这些数据是什么样的结构,它们之间有什么关系等。③完成系统详细设计:包括采用C语言定义相关的数据类型;写出各模块的类C码算法;画出函数的调用关系图。④调试分析、设计体会、测试数据:准备典型的测试数据和测试方案,包括正确的输入及输出结果和含有错误的输入及输出结果;程序调试中遇到的问题以及解决问题的方法;课程设计过程经验教训、心得体会。

就是每句后有注释

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

一个完整的c程序如下,程序在win-tc和Dev-c++下都调试通过。

#include<stdioh>

#include<timeh>

#include<stdlibh>

int main()

{

int stime,a,z,t,i,c,m,g,s,j,k,l[4]; /j:数字正确的位数 k:位置正确的位数/

long ltime;

ltime=time(NULL); /l:数字相同时,人所猜中数字的正确位置/

stime=(unsigned int)ltime/2;

srand(stime);

z=random(9999); /计算机想一个随机数/

printf("I have a number with 4 digits in mind,please guess\n\n");

for(c=1;;c++) /c: 猜数次数计数器/

{

printf("Enter a number with 4 digits:");

scanf("%d",&g); /请人猜/

a=z;j=0;k=0;l[0]=l[1]=l[2]=l[3]=0;

for(i=1;i<5;i++) /i:原数中的第i位数。个位为第一位,千位为第4位/

{

s=g;m=1;

for(t=1;t<5;t++) /人所猜想的数/

{

if(a%10==s%10) /若第i位与人猜的第t位相同/

{

if(m&&t!=l[0]&&t!=l[1]&&t!=l[2]&&t!=l[3])

{

j++;m=0;l[j-1]=t; /若该位置上的数字尚未与其它数字“相同”/

} /记录相同数字时,该数字在所猜数字中的位置/

if(i==t) k++; /若位置也相同,则计数器k加1/

}

s/=10;

}

a/=10;

}

printf("Correctly guessed %d digits,",j);

printf("and guessed %d digits in exact position\n\n",k);

if(k==4) break; /若位置全部正确,则人猜对了,退出/

}

printf("Now correctly guessed the whole number after %d times\n",c);

}

欢迎分享,转载请注明来源:表白网

原文地址:https://h5.hunlipic.com/biaobai/4160084.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2024-04-20
下一篇2024-04-20

发表评论

登录后才能评论

评论列表(0条)

    保存