Windows静态库和动态库的创立和行使,操作系统实验及代码

by admin on 2019年2月18日

     欢迎来到windows编程的社会风气,先给咱们的windows打个招呼吧:

网络编程1. 套接字编程基本知识

操作系统实验及代码(全),操作系统实验代码

操作系统是总括机有关标准的一门极其紧要的专业课,但实验课的时候很三个人不知情代码应该怎么写,这里贴出博主使用过的一局地,亲测可行。 

偶们在实际上的编程开发中,平常会遭逢运转时不知所可找到有个别DLL文件大概链接时不或者找到某些LIB文件。然后,我们就从头乱GOOGLE一下,然后将VS二零零六的安装改变一下,或然就Ok了,大家将别人付出的DLL只怕LIB导入到大家的编程中,那么这一个lib,DLL到底是怎么样啊?下边,偶就细细道来。 

#include
<Windows.h>

1.首先网络编程使用C++,要引入一些库

难题1:Windows进度的成立与销毁

履新时间:2017-10-26

内容及须要:


明白Windows进度的始建和销毁API的调用方法;编程代码,在先后中创制和销毁3个Word进度;

② 可以挂起和激活被创设进度的主线程;

③ 通过Windows进度管理器查看系统经过列表的生成。

试行指点:

①创立进度的API

BOOL CreateProcess(

  LPCTSTR lpApplicationName,

  LPTSTR lpCommandLine,

  LPSECURITY_ATTRIBUTES lpProcessAttributes,

  LPSECURITY_ATTRIBUTES lpThreadAttributes,

  BOOL bInheritHandles,

  DWORD dwCreationFlags,

  LPVOID lpEnvironment,

  LPCTSTR lpCurrentDirectory,

  LPSTARTUPINFO lpStartupInfo,

  LPPROCESS_INFORMATION lpProcessInformation

);

例程:

 1 void main( VOID ){
 2     STARTUPINFO si;
 3     PROCESS_INFORMATION pi;
 4     ZeroMemory( &si, sizeof(si) );
 5     si.cb = sizeof(si);
 6     ZeroMemory( &pi, sizeof(pi) );
 7     // Start the child process. 
 8     if( !CreateProcess( NULL, // No module name (use command line). 
 9         "MyChildProcess", // Command line. 
10         NULL,             // Process handle not inheritable. 
11         NULL,             // Thread handle not inheritable. 
12         FALSE,            // Set handle inheritance to FALSE. 
13         0,                // No creation flags. 
14         NULL,             // Use parent's environment block. 
15         NULL,             // Use parent's starting directory. 
16         &si,              // Pointer to STARTUPINFO structure.
17         &pi )             // Pointer to PROCESS_INFORMATION structure.
18         ) {
19             ErrorExit( "CreateProcess failed." );
20     }
21     // Wait until child process exits.
22     WaitForSingleObject( pi.hProcess, INFINITE );
23     // Close process and thread handles. 
24     CloseHandle( pi.hProcess );
25     CloseHandle( pi.hThread );
26 }

销毁进度API

BOOL TerminateProcess(

  HANDLE hProcess,

  UINT uExitCode

);

③ 挂起过程的主线程API

DWORD SuspendThread(

  HANDLE hThread

);

④激活进度的主线程API

DWORD ResumeThread(

  HANDLE hThread

);

⑤历程查看器

1 #include<iostream> 2 #include<windows.h> 3 using
namespace std; 4 void main( VOID ) 5 { 6 STARTUPINFO si; 7
PROCESS_INFORMATION pi; 8 /** 9 * 那里填个人的word可执行文件的路径
10 * ps:”\”须求开展转义 11 **/ 12 TCHAR
szCommandLine[]=TEXT(“D:\\Microsoft
Office\\Office14\\WINWORD.EXE”); 13 ZeroMemory(&si, sizeof(si) ); 14
si.cb= sizeof(si); 15 ZeroMemory(&pi, sizeof(pi) ); 16
if(!CreateProcess( NULL, szCommandLine, NULL,NULL, FALSE,0,NULL,
NULL,&si,&pi ) ) 17 { 18 fprintf(stderr,”进度创立战败!”); 19 } 20 int
x; 21 while(1) 22 { 23 cout <<
“请输入要选择的操作:\n1:成立进度\n2:销毁进程\n3:挂起过程\n4:激活进度\n0:退出\n”;
24 cin >> x; 25 switch(x) 26 { 27 case 1: 28 if(CreateProcess(
NULL, szCommandLine, NULL,NULL, FALSE,0,NULL, NULL,&si,&pi ) ) 29
fprintf(stderr,”进度创立成功!”); 30 else 31 cout <<
“进程成立失利!”<<endl; 32 break; 33 case 2: 34
if(TerminateProcess(pi.hProcess,0)) 35
cout<<“销毁进度成功”<<endl; 36 else 37
cout<<“销毁失利!”<<endl; 38 break; 39 case 3: 40
if(SuspendThread(pi.hThread)) 41 cout<<“挂起经过成功”<<endl;
42 else 43 cout<<“挂起失利”<<endl; 44 break; 45 case 4: 46
if(ResumeThread(pi.hThread)) 47 cout<<“激活进度成功”<<endl;
48 else 49 cout<<“激活失利”<<endl; 50 break; 51 case 0: 52
exit(0); 53 default: 54 cout<<“输入有误不正确”<<endl; 55 }
56 } 57 }

 

四处革新中!!!

 

作者:耑新新,发布于  博客园

转载请声明出处,欢迎邮件互换:[email protected]

操作系统是总计机有关规范的一门极其首要的专业课,但实验课的时候很多个人不知底代码应…

率先,偶们说第一个:静态链接库(Static Libary)

#include
<iostream>

         #include <Windows.h>

偶们用VS二零零六做3个静态链接库先

using namespace  std;

         并且须要利用静态链接库,

开辟VS二〇〇五,新建à项目(staticCai)àWin32控制台应用程序

int  main()

         那里运用的是编译语句#Windows静态库和动态库的创立和行使,操作系统实验及代码。pragma comment(lib,”ws2_32.lib”) 约等于将ws2_32.lib静态链接库插手到项目中,效果和增进引用是平等的。

 

{

         ws2_32.lib应和的是ws2_32.dll,提供对于大规模互连网编程的API接口协助,使用其中的互连网接口就须要将ws2_32.dll添加到工程,否则须求动态的加载ws2_32.dll。

新建static_lib.h 和static_lib.cpp 七个文本,那八个文本的情节如下:

       int iSelect=MessageBox(NULL,Windows静态库和动态库的创立和行使,操作系统实验及代码。TEXT(“你好,windows世界,我来了!”),TEXT(“你好,世界”),MB_OKCANCEL);

  1. WSAStartup 函数的介绍

static_lib.h:

       if(iSelect==IDOK)

         WSAStartup是Windows SockNDs Asynchronous(Windows 异步套接字) 的起步命令, windows下的互联网编程软件Winsock1,
Winsock2的三个命令。

home88一必发, 

       {

         WSAStartup函数完结对Winsock服务的初叶化,由此须要调用WSAStartup函数。使用Socket程序在运用Socket此前务必调用WSAStartup函数。该函数的第三个参数表示程序请求使用的Socket版本,高字节表示副版本,低字节表示主版本;操作系统利用第四个参数重临请求的Socket的版本音信。当3个应用程序调用WSAStartup函数的时候,操作系统依照请求的Socket版本来搜索响应的Socket库,绑定到Socket库到应用程序中。在其后的程序中可以调用Socket库中的其余的socket函数。

int add(int x,int y);

              *cout<<“you select ok “<<endl*;

         int WSAStartup(WORD wVersionRequest,
LPWSADATA lpWSAData);

int substract(int x , int y);

       }else

         参数介绍:

 

       {

                  
wVersionRequest: 七个双字节数值, 使用MAKEWOKoleosD(2,2)生成;

static_lib.cpp:

              *cout<<“you select cancel”<<endl*;

                   lpWSAntec: 指向多少个WSADATA的数据结构的指针,用于吸纳Windows Sockets已毕的底细。

 

       }

         If the function return 0, 表示成功。

#include “static_lib.h”

       *system*(“pause”);

         开启Windows Sock
Asynchronous,对应当程序为止的时候,就应当关闭,WSACleanup()用于接触于Socket库的绑定并且释放掉Socket库所占有的系统财富。

 

       return  0;

3.科普的有个别函数在WinSocket编程中利用的介绍

int add(int x,int y)

}

3.1 gethostname() // 获取当地主机的主机名

{

   所谓windows编程就是指通过调用Windows
API来和操作系统交互的编程格局。API就是与操作系统交互的各类功用函数,MessageBox就是三个API,调用它就可以弹出1个对话框。

         函数原型: int
PASCAL FAEvoque gethostname( char FA智跑 * name, int namelen);

       return x + y;

        
Name:用于指向主机名缓冲区的指针,namelen: 缓冲区的大小。

}

         Return Value:无不当的话,再次回到0,反之重临对应的错误代码。

 

#include <iostream>

int substract(int x,int y)

#include <Windows.h>

{

using namespace std;

       return x – y;

 

}

#pragma comment(lib,”ws2_32.lib”)

下一场编译,生成消除方案,好,那样不出意外会在debug文件夹(与staticCai并列)下生成3个staticCai.lib文件,好了,那几个就是大家做好的静态链接库。上边,我们看看怎么用这几个静态链接库。我们再新建1个win32控制台程序,新建main.cpp内容如下:

int main(){

#include <iostream>

    WSADATA wsa ;//
WSADATA 结构是用来保存函数WSAStartup 再次回到的Windows
socket初始化音信

#include “static_lib.h”

    if(WSAStartup(MAKEWORD(2,1),&wsa) != 0){

#pragma comment(lib, “static.lib”)

        cout << “套接字初阶化失败”<<  endl;

using namespace std ;

        Sleep(3000);

 

        exit(-1);

int main()

    }else{

{

        cout << “套接字开始化成功” << endl;

       cout << add(3 ,4) << endl ;

    }

       cout << substract(5 , 3) << endl ;

 

       return 0 ;

    char buf[255];

}

 

并且将staticCai.lib和static_lib.h那三个文本拷贝到与main.cpp并列的文件夹下。然后,大家编译,链接,执行顺序,就会出结果了

    if( gethostname(buf,sizeof(buf)) ==
SOCKET_ERROR  ){

#pragma comment(lib,
“static.lib”)那句和我们在 项目à属性à连接器à添加正视项 的功力是一样的。至此,如何做静态链接库以及怎么用静态链接库就化解了。以后,大家把刚刚拷贝过来的staticCai.lib给删了,大家发现,程序照旧执行,不过无法再链接了。所以,大家得出那样的结论:我们再链接的时候需求静态链接库,一旦链接成功,生成了可执行文件,那么,静态链接库就不再须要了。

        cout << “获取当地主机的Name败北:”<<WSAGetLastError()<< SOCKET_ERROR <<
endl;

协助,偶们说第二个:动态链接库(dynamic link Libary)

    }else{

同一,大家来做三个动态链接库,和下面的步骤一样,先建工程,唯有最后一步稍有差距

        cout <<“本地主机的名字是:” << buf << endl;

 

    }

然后,新建Dll.cpp文件(那里大家就不做.h文件了),敲入一下内容:

    WSACleanup();// 落成清理工作

#define  DLL_API _declspec(dllexport)

    return 0;

#include <iostream>

}

using namespace std;

3.2得到主机的IP
gethostbyname(const char* name);

DLL_API int add(int a,int b)   //落成多少个整数相加

hostent 是3个数据结构,保存从gethostbyname重临的新闻,包涵主机的IP地址类型IPV4,IPV6,主机的别名,主机的IP长度,h_addr_list[]

{

         必要动用in_addr 类型保存二个IP地址,并且须要将IP地址转换到为字符串的格式,使用的是const char * inet_ntoa(in_addr in); 将pht->h_addr_list[i] 转换来为(in_addr*)的指针,然后再通过指针获取器内容,转换来为字符串的样式。

       return a+b;

hostent* pht =
gethostbyname(“www.google.com”);

}

    if(pht==NULL){

DLL_API int subtract(int a,int b)   //完结多少个整数相减

        cout << WSAGetLastError() <<
endl;

{

    }else{

       return a-b;

        //cout << AF_INET <<
endl;

}

        cout << “h_addrtype:” << 
pht->h_addrtype << endl;

然后,我们编译,生成化解方案,就会在debug文件夹下生成dllCai.dll和dllCai.lib。好,至此,动态链接库就抓牢了,下边大家来看怎么用,新建多少个win32控制台程序,新建main.cpp内容如下:

        cout << “h_aliases:” <<
pht->h_aliases << endl;

#include <iostream>

        cout << “h_length:” <<
pht->h_length << endl;

using namespace std ;

        cout << “h_name:”<<
pht->h_name << endl;

#pragma comment(lib, “DLL.lib”)

        for(int i = 0; pht->h_addr_list[i] !=
NULL;i++){

extern int add(int a,int b);

            in_addr addr = *(in_addr*)
pht->h_addr_list[i];

extern int subtract(int a,int b);

            cout <<inet_ntoa(addr) <<
endl;

int main()

        }

{

    }

       cout << add(3 ,4) << endl ;

 

       cout << subtract(5 , 3) << endl ;

#include <iostream>

       return 0 ;

#include <Windows.h>

}

#include <process.h>

接下来把dllCai.dll和dllCai.lib拷贝到与main.cpp并列的目录下。接着,编译,链接,执行,就会面到和上三回一样的结果了。然后,我们把dllCai.lib给删了,程序依然执行,但是不恐怕再链接了,接着,大家把dllCai.dll给删了,程序可以再编译,链接,不过执行的时候就黄了。所以,大家说:对于动态链接库,链接的时候要求.lib文件,运维的时候必要.dll文件。 

using namespace std;

至今,静态链接库和动态链接库我们就说完了,大家做一下对照和互补:

 

1 、 两个lib文件

 

作者们发现,无论是静态链接库如故动态链接库,最后都有lib文件,那么双方分别是怎么吗?其实,多个是一心差别等的东西。staticCai.lib的轻重缓急为4KB,dllCai.lib的轻重缓急为2KB,静态库对应的lib文件叫静态库,动态库对应的lib文件叫导入库。实际上静态库本人就隐含了实际履行代码、符号表等等,而对于导入库而言,其实际的施行代码位于动态库中,导入库只含有了地址符号表等,确保程序找到相应函数的一部分主导地址新闻。

 

2 、 对于静态链接库,大家在编译和链接的时候曾经将有所的代码都导入进来,由此,当生成可执行文件未来,可执行文件包括全部的代码。因而,在可执行文件运维时就不再需求静态库了,那也是干什么大家删掉staticCai.lib程序照旧执行;而对于动态链接库,实际上,可执行文件不带有DLL中的内容,只是透过导入库(.lib)知道了相应的地点音讯,因而,可执行文件在运维时动态得去加载DLL,那也是干什么大家删掉dllCai.dll后先后就无法履行了。

#pragma comment(lib,”ws2_32.lib”)

3 、 对于DLL,我们是可以不要lib文件的。

 

比方不要lib文件,大家可以透过函数指针的利用达到我们的目标:

int main(){

#define  DLL_API _declspec(dllexport)

    WSADATA wsa ;//
WSADATA 结构是用来保存函数WSAStartup 重返的Windows
socket初阶化音讯

#include <iostream>

    if(WSAStartup(MAKEWORD(2,1),&wsa) != 0){

using namespace std;   //注意那里的extern “C” , 那里不可不加

        cout << “套接字早先化失败”<<  endl;

extern “C” DLL_API int add(int a,int b)   //完毕七个整数相加

        Sleep(3000);

{

        exit(-1);

       return a+b;

    }else{

}

        cout << “套接字初步化成功” << endl;

extern “C” DLL_API int subtract(int a,int b)   //完毕多个整数相减

    }

{

 

       return a-b;

    char buf[255];

}

 

#include <iostream>

    if( gethostname(buf,sizeof(buf)) ==
SOCKET_ERROR  ){

#include <Windows.h>

        cout << “获取当地主机的Name失利:”<<WSAGetLastError()<< SOCKET_ERROR <<
endl;

using namespace std ;

    }else{

 

        cout <<“本地主机的名字是:” << buf << endl;

typedef int (*func)(int x , int y);  //函数指针

    }

int main()

   

{

    hostent* pht = gethostbyname(buf);

       HINSTANCE hInstance = LoadLibrary(“DLL.dll”);

    if(pht==NULL){

       if(hInstance == NULL)

        cout << WSAGetLastError() <<
endl;

       {

    }else{

              cout << “SB” << endl ;

        //cout << AF_INET <<
endl;

              return 0;

        cout << “h_addrtype:” << 
pht->h_addrtype << endl;

       }

        cout << “h_aliases:” <<
pht->h_aliases << endl;

       func add = (func)GetProcAddress(hInstance, “add”);

        cout << “h_length:” <<
pht->h_length << endl;

       func sub = (func)GetProcAddress(hInstance, “subtract”);

        cout << “h_name:”<<
pht->h_name << endl;

       cout << (*add)(3,4) << endl ;

        for(int i = 0; pht->h_addr_list[i] !=
NULL;i++){

       cout << (*sub)(5,3) << endl ;

            in_addr addr = *(in_addr*)
pht->h_addr_list[i];

}

            cout << “IP:”
<<inet_ntoa(addr) << endl;

引人侧目,那种措施没有用lib文件方便,如果为了每一遍调用二个函数还要协调再弄二个函数指针,多辛劳啊,所以,大家在骨子里支出中,用的洋洋的第2方伸张库,旁人都是提供的:

        }

.h  文件(类,函数的宣示)

    }

.dll 文件(类或函数的兑现)

 

.lib 文件(导入库)

    SOCKET serverSocket =
socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

 

    if(serverSocket == INVALID_SOCKET){

小结:

        cout << “创设套接字战败” << endl;

一、静态库

        cout << WSAGetLastError() <<
endl;

*
静态库是把程序运维时要求拔取的函数编译在一个二进制文件中,扩充名为.lib。当程序link时把静态库中的二进制数据和程序其他数据放到一起。程序运转时不在须求lib和dll文件的资助。那样做的弊端是付出出来的次第占用磁盘空间较大。尤其是windows系统中自然就有或很多程序运营都亟需的函数
完全没有须求每一遍开发顺序时都要选取各自的静态库。

        Sleep(3000);

* 静态库为.lib文件格局存在

        exit(-1);

*
链接后爆发的可执行文件包罗了富有须求调用的函数的代码,因而占有磁盘空间较大

    }

*
如果有三个(调用相同库函数的)进度在内存中间时运营,内存中就存有多份相同的库函数代码,因而占有内存空间较多。

 

二、动态库

    sockaddr_in  serverAddress;

*
动态库在支付时仅是把dll中的函数名和参数放到应用程序中,应用程序运营时根据函数名和参数调用dll中的函数来运维,那样操作系统中的应用程序可以同
时采用同一个dll。可以有效地节约硬盘空间,当然如此做使得程序设计更有层次。也便宜软件工程师的分工和消息安全

    int listen_port = 8999;

*
动态库以.dl文件方式存在,且一般都有1个一见倾心的引入库以.lib文件格局存在。纯财富dll不生成.lib引入库。

   
memset(&serverAddress,0,sizeof(serverAddress));

  
>引入库和静态库的增添名均为*.lib,然而引入库仅包涵部分函数名和参数音信,没有函数体,是为调用动态库服务的,它和动态库的关联一定于.h文件和.cpp文件之间的关系;

    serverAddress.sin_family = AF_INET;

* 动态库三种绑定方式

    serverAddress.sin_port =
htons(listen_port);

   >静态绑定(static blnding)
使用静态绑定的程序在一始发载入内存的时候,载入程序就会把程序有所调用到的动态代码的地址算出、分明下来。那种方法使程序刚运营时的开始化时间较长,但是一但形成动态装载,程序的周转速度就很快。

    serverAddress.sin_addr.S_un.S_addr =
htonl(INADDR_ANY);

    2动态绑定(dynamic binding)  
使用那种方法的顺序并不在一初叶就成功动态链接,而是直到真正调用动态库代码时,载入程序才总括(被调用的这部分)动态代码的逻辑地址,然后等到有些时
候,程序又需要调用其它某块动态代码时,载入程序才又去统计那有个别代码的逻辑地址。所以,那种措施侄程序伊始化时间较短,但运维期间的属性比不上静态绑定
的次序。

 

* 使用动态库的三种方法(windows)

    if( bind(serverSocket,(sockaddr*)&serverAddress,
sizeof(serverAddress)) == SOCKET_ERROR){

  >方法一: load-time dynamic linking 
在要调用dll的应用程序链接时,将dll的输入库文件(import
library,.lib文件)包含进去。具体的做 法是在源文件开头加一句#include
,然后就足以在源文件中调用dlldemo.dll中的输出文件了。

        cout << “绑定套接字端口失利” << endl;

  >方法二: run-time dynamic linking 

        cout << WSAGetLastError() <<
endl;

毋庸在链接时带有输入库文件,而是在源程序中应用LoadLibrary或LoadLibraryEx动态的载入dll。

        Sleep(3000);

        exit(-1);

    }else{

        cout << “成功绑定端口:” << listen_port << endl;

    }

 

    if( listen(serverSocket,SOMAXCONN) ==
SOCKET_ERROR){

        cout <<“监听失利” << WSAGetLastError() << endl;

 

        Sleep(3000);

        exit(-1);

    }else{

        cout << “成功监听端口:”<< listen_port  << endl;

    }

 

   

   

 

    while(true){

        cout << “yang” << endl;

        SOCKET chatSocket;

        sockaddr_in clientAddress;

       
memset(&clientAddress,0,sizeof(clientAddress));

        int addrlen = sizeof(clientAddress);

        if( (chatSocket =
accept(serverSocket,(sockaddr*)&clientAddress,&addrlen))==
SOCKET_ERROR){

            cout << “接受连接败北” << WSAGetLastError()<< endl;

            continue;

        }else{

            cout << “接受来自” << inet_ntoa(clientAddress.sin_addr)
<<“的连接”<< endl;

        }

 

 

    }

 

    WSACleanup();// 完结清理工作

    return 0;

}

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图