VS2010静态库、动态库

来源:互联网 发布:两晋通俗演义 知乎 编辑:程序博客网 时间:2024/05/07 13:25
1.VS2010新建lib工程
File->new->Project->Win32 Application->application setting的时候选择static library,去掉Precompiled header

新建头文件static_lib.h

int add(int x, int y);
int add(int x, int y, int z);
int sub(int x, int y);

新建源文件static_lib.cpp

#include "static_lib.h"

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

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

int sub(int x, int y)
{
        return x - y;
}

Build->Build Solution.
没有问题的话会在static_lib\Release和static_lib\Debug目录下生成static_lib.lib文件。这就是静态库。

使用静态库:
新建工程Use_static_lib。把上一步的头文件static_lib.h以及生成的static_lib.lib文件拷贝到新建工程的目录下。
新建main.cpp

#include <iostream>
#include "static_lib.h"

#pragma comment (lib, "static_lib.lib")

using namespace std;

int main()
{
       cout<<add(3, 4, 5)<<endl;
       system( "pause");
        return 0;
}

运行程序,成功输出12.

2.VS2010新建dll工程
与1中类似,到application setting的时候,选择DLL。
VS2010自动生成了几个文件。
dll_lib.h

#ifdef DLL_LIB_EXPORTS
#define DLL_LIB_API __declspec (dllexport)
#else
#define DLL_LIB_API __declspec (dllimport)
#endif

// This class is exported from the dll_lib.dll
class DLL_LIB_API Cdll_lib {
public:
       Cdll_lib( void);
        // TODO: add your methods here.
};

extern DLL_LIB_API int ndll_lib;

DLL_LIB_API int fndll_lib( void);

这里是一个类,一个变量和一个普通函数的申明。

dll_lib.cpp

#include "stdafx.h"
#include "dll_lib.h"


// This is an example of an exported variable
DLL_LIB_API int ndll_lib=0;

// This is an example of an exported function.
DLL_LIB_API int fndll_lib( void)
{
        return 42;
}

// This is the constructor of a class that has been exported.
// see dll_lib.h for the class definition
Cdll_lib::Cdll_lib()
{
        return;
}

这里是头文件中申明的实现。

加上自己的函数:
在dll_lib.h头文件中加如下内容:

//my own functions
DLL_LIB_API int add( int x, int y);
DLL_LIB_API int sub( int x, int y);

在dll_lib.cpp源文件中写函数的实现:

//my own functions
DLL_LIB_API int add( int x, int y)
{
        return x + y;
}

DLL_LIB_API int sub( int x, int y)
{
        return x - y;
}

Build->Build Solution.
编译成功,会生成dll_lib.lib和dll_lib.dll两个文件。

使用动态库:
动态库的使用有两种方式:隐式调用和显式调用。
1.隐式调用
这种调用方法中需要.h文件,.lib文件和.dll文件。
新建工程,把dll_lib.h文件,dll_lib.lib文件和dll_lib.dll文件拷贝到工程目录下
新建main.cpp

#include <iostream>
#include "dll_lib.h"

using namespace std;

#pragma comment (lib, "dll_lib.lib")//加??载?dll的??lib引?y导??

int main()
{
       cout<<add(2, 4)<<endl;
       system( "pause");
        return 0;
}

编译,连接,运行成功。如果去掉dll_lib.lib程序会编译失败,如果去掉dll_lib.dll程序运行失败,因为找不到函数的代码。

2.显示调用
这种调用方法只需要lib_dll.dll就行。
先定义函数指针,使用LoadLibrary()加载dll,使用GetProcAddress()获取函数的地址。然后就可以使用这个函数了。

但是这里有一个问题。涉及到C和C++对函数名的符号定义。

如果dll中是用C定义的int add(int, int)函数,可以这么用
typedef int (*func) (int, int); //函数指针

HINSTANCE hInstance = LoadLibrary("lib_dll.dll"); //加载dll
ASSERT(hInstatce != NULL);

func add = (func)GetProcAddress(hInstance, "add"); //寻找函数名为add的函数地址
一切都很好,没有问题。

那么如果是C++呢?
如果在dll中定义了两个函数
int add(int, int, int);
int add(int, int);
那么func add = (func)GetProcAddress(hInstance, "add"); //寻找函数名为add的函数地址
得到的是哪个函数的地址呢?
答案是得不到任何一个函数的地址。因为找不到函数符号为add的函数,所以得不到函数地址。这两个函数可能为_add_int_int和_add_int_int_int,要看dll中的函数名,可以使用dumpbin工具。

在dll中使用extern "C" 可以让编译器安装C语法进行编译。
http://www.cppblog.com/Macaulish/archive/2008/06/17/53689.html

使用C++编译的dll更详细的参考如下:
http://blog.csdn.net/btwsmile/article/details/6676802

原创粉丝点击