您的位置:首页 > 其它

vs2010生成和使用.dll,.lib和.exe文件

2014-07-22 15:06 411 查看
刚学会用vs,一切皆小白,人笨手要勤快,随手作笔记。今天主要是记录怎样用vs2010生成和使用动态库文件.dll,静态库文件.lib和可执行文件.exe。

参考博文:/article/6025467.html(这篇写得非常好,思路很清晰)

/article/10443050.html

1、vs2010生成.dll

我们用一个简单的两整数相加的例子来说明创建dll的方法。本例采用VS2010,使用C++编程语言,具体操作步骤如下。
新建一个项目,选择Win32 控制台应用程序,项目名为add,解决方案名为DLLTEST(注意“为解决方案创建目录”是勾选上的),点击确认,接着点击下一步,到Application Settings,选择应用程序类型为dll,并勾选“导出符号”,点击完成。完成这一步之后,VS界面上左边的解决方案资源管理器中将会看到向导自动生成的文件列表,如下图所示。



add.cpp和add.h中给出了3种类型的example,分别为导出变量nadd、导出函数fnadd以及导出类Cadd。本例只考虑导出函数,所以将导出变量和导出类的样例部分都删掉。即将add.h修改为:
// 下列 ifdef 块是创建使从 DLL 导出更简单的
// 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 ADD_EXPORTS
// 符号编译的。在使用此 DLL 的
// 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
// ADD_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
// 符号视为是被导出的。
#ifdef ADD_EXPORTS
#define ADD_API __declspec(dllexport)
#else
#define ADD_API __declspec(dllimport)
#endif

extern "C" ADD_API int add(int,int);   //注意这里加上extern "C",不然后面调用会出错
//ADD_API int add(int,int);
注意上面代码中的extern "C",虽然在源代码add.cpp中定义的函数名是add,但在dll二进制文件中,经过编译器的“加工”,它实际上变成另外一个名称。这个另外的名称在原有函数名add的基础上加上了一些函数输入输出参数的信息,这样做主要是为函数重载服务的,所以如果直接这样调用dll,程序就会一直提示找不到dll,因为函数名不匹配,解决方法至少有两种:一是运用extern "C"修饰add,就像我们上面那样;二是运用模块定义文件.def。后者的效果更好,具体可参考/article/6025467.html的详解。

add.cpp修改为:
// add.cpp : 定义 DLL 应用程序的导出函数。

#include "stdafx.h"
#include "add.h"

// 这是导出函数的一个示例。
ADD_API int add(int x,int y)
{
int sum=x+y;
return sum;
}
然后选择菜单生成->生成 add,输出窗口提示add.dll生成成功,如下图所示。



2、vs2010调用.dll

2.1 隐式调用.dll

即通过lib和头文件,该方法需要DLL工程经编译后产生的lib文件,此文件包含DLL允许应用程序调用的所有函数列表。直接在上面已建立好的解决方案DLLTEST中新建一个win32项目或者是重新建一个新的解决方案然后再新建项目均可(前一种将相关的项目放到一起,有利于组织),我们这里重新建个解决方案,然后新建win32项目--填写项目名UseDll1--确定--下一步--控制台项目,下面选择空项目--完成,将刚才生成的add.h,add.dll和add.lib拷至当前工程目录下(也可以不拷到当前目录下,不拷的话就要在属性里面指定包含目录和库目录),然后在左侧解决方案资源管理器中右击源文件--添加新建项--选择c++文件,命名为main,main.cpp中的代码为:

#include <iostream>
#include "add.h"
using namespace std;
#pragma comment(lib, "add.lib")
int main( int argc, char** argv ){
int x,y,sum;
cout<<"hello world"<<endl;
cout<<"请输入x,y的值:";
cin>>x>>y;
sum=add(x,y);
cout<<"x和y的和为:"<<sum<<endl;
system("pause");
}
隐式调用过程完成。

2.2 显示调用.dll

显式调用只需要一个.dll文件就可以了,灵活性更好,更新模块方便;相对的,程序员需要做的事情更多,使用方法更为复杂。当只提供dll文件而没有其相关的lib文件和头文件的情况下,只能使用显示调用。
这里还是重新建个解决方案,选择Win32 控制台程序,输入项目名为UseDLL2,确定--下一步--控制台项目,下面选择空项目--完成。将add.dll拷至工程目录下,添加源文件main.cpp,main.cpp中的代码为:

#include<Windows.h>  
#include<iostream>  
typedef int(*FUNA)(int,int);  

using namespace std;
int main()  
{  
    const char* dllName = "add.dll"; 
    const char* funName = "add";    
    HMODULE hDLL = LoadLibrary(dllName);  
    if(hDLL != NULL)  
    {  
        FUNA fp1 = FUNA(GetProcAddress(hDLL,funName));  
        if(fp1 != NULL)  
        {  
            int x,y,sum;
cout<<"请输入x和y的值:";
cin>>x>>y;
            sum=fp1(x,y);  
cout<<"x,y的和为:"<<sum<<endl;
system("pause");
        }  
        else  
        {  
            cout<<"无法找到函数 "<<funName<<endl;  
        }  
        
        FreeLibrary(hDLL);  
    }  
    else  
    {  
        cout<<"无法加载库 "<<dllName<<endl;  
    }  
    return 1;  
}  
显示调用过程完成。

上面的显示调用过程有以下注意点:

包含头文件Windows.h,原因在于程序中用到了LoadLibrary、FreeLibrary、GetProcAddress等Win32 API函数。
FUNA是函数指针类型的声明。
当程序不再使用dll时,应该调用FreeLibrary及时释放它占用的内存空间。
如果在const char* dllName和funName底部出现红色波浪线提示,说明采用的字符集不匹配,需要修改项目UseDLL2的属性字符集为Not Set。

3、vs2010生成.lib



新建项目--win32控制台项目--填写项目名Static--确定--下一步--应用程序类型:选择静态库,静态库项目没有main函数,也没有像dll项目中的dllmain,创建完项目后自己添加add.h和add.cpp文件,add.h中的代码为:

#ifndef _MYLIB_H_
#define _MYLIB_H_

extern "C" int add(int,int);

#endif
add.cpp中的代码为:
#include "stdafx.h"
#include "add.h"
#include <iostream>

int add(int x,int y)
{
int sum=x+y;
return sum;
}
然后点击生成--生成add,就可在Debug文件夹下得到生成的add.lib,只有一个add.lib文件,如下图所示。



4、vs2010调用.lib

要调用静态库,需要使用.h文件和.lib文件,同样新建工程,工程建完之后,将add.h和add.lib拷至工程目录下,将lib添加到项目属性--链接器--输入--附加依赖项(或者直接在源代码中加入#pragma comment(lib, “add.lib”)),在源文件中添加add.h头文件,在工程中新建main.cpp,代码为:

#include <iostream>
#include "add.h"
using namespace std;
#pragma comment(lib, "add.lib")

int main( int argc, char** argv ){

int x,y,sum;
cout<<"hello world"<<endl;
cout<<"请输入x,y的值:";
cin>>x>>y;
sum=add(x,y);
cout<<"x和y的和为:"<<sum<<endl;
system("pause");
}
调用过程结束。

3、vs2010生成可执行文件

如果当前项目调试通过,那么vs2010本身就会在当前工程目录的Debug文件夹下生成.exe可执行文件,非常方便。假设现在要实现一个加法程序。vs2010新建c++控制台程序,然后对资源管理器中的头文件点击“添加新建项”,选择头文件.h格式,头文件命名为add.h,add.h中输入代码:

int add(int,int);

然后对资源管理器中的源文件点击“添加新建项”,选择.cpp格式,该源文件命名为add.cpp,add.cpp中输入代码:

//#include  "add.h"

int add(int x,int y){
int sum=x+y;
return sum;
}

最后再来编写main函数,同样对资源管理器中的源文件点击“添加新建项”,选择.cpp格式,该源文件命名为main.cpp,main.cpp中输入代码:

#include <iostream>
#include "add.h"
using namespace std;
int main( int argc, char** argv ){

int x,y,sum;
cout<<"hello world"<<endl;
cout<<"请输入x,y的值:";
cin>>x>>y;
sum=add(x,y);
cout<<"x和y的和为:"<<sum<<endl;
system("pause");
}
点击启动调试,这个程序会生成成功,结束后会发现在Debug文件下生成了一个.exe文件,双击就可运行。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: