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语法进行编译。
使用C++编译的dll更详细的参考如下: