动态链接库程序的编写

看了孙鑫老师的视频关于DLL的一章的笔记:

 

情形一:自己编写DLL,自己调用
在DLL中编写的输出函数,必须要在函数前面写上_declspec(dllexport),其中declspec是declare   special的意思。如:

在编译DLL的时候,会生成一个lib文件,如a.lib
而在主程序中要调用这个函数的话,就要先声明下:
extern int add(int a, int b);或者_declspec(dllimport) int add(int a, int b);
而且还要将a.lib文件放在主程序文件所在的目录下。不然链接的时候会报错。还没完!还要设置下工程--设置--Link下的Object/library modules写上a.lib就好了!那么我们说说这个lib的作用吧,实际上这个lib提供了一个重定位表。当然这样算好了吗?还没有啊!此时编译还是要报错的!因为找不到a.dll,此时还要将a.dll放到主程序exe所在的目录。注意像这样的就是一个静态调用(隐式调用)了,动态调用时不需要包含头文件和库文件的,只需要DLL就OK!

情形二:别人A编写DLL,自己B调用
要求A在编写DLL的时候,用一个头文件dll1.h来说明导出了哪些函数
_declspec(dllimport) int add(int a, int b);
同时B要包含头文件dll1.h,此时就不用声明_declspec(dllimport) int add(int a, int b);

一般来说,是这样来写的:
对于A工程里有两个文件:
DLL1.cpp和DLL1.h
DLL1.h:

 

#ifdef DLL1_API
#else
#define DLL1_API _declspec(dllimport)
#endif

DLL1_API 
int add(int a, int b);

DLL1.cpp:

#define DLL1_API _declspec(dllexport)
#include 
"DLL1.h"

int add()
{
 
return a+b;
}

 

情形三:在DLL中怎么导出一个类

在class和类名之间加入DLL1_API ,如:

Class DLL1_API Point
{
public:
 void output(int x, int y);
}
而实现的过程要在CPP中完成:
void Point::output(int x, int y)
{
 ...
}

这种情况下,导出的是整个Point类,那如果我只想导出Point类中的某一个函数怎么办呢?那么只需要在该函数前面加上DLL1_API即可,如:
Class  Point
{
public:
 DLL1_API void  output(int x, int y);
}

情况四:DLL中的函数是乱码,怎么解决?
首先新建一个DLL源文件Dll2.cpp里面写上自己的函数:

 

int add(int a, int b)
{
 
return a+b;
}

int sub(int a, int b)
{
 
return a-b;
}


然后手工新建一个空的模块文件(一个模块的后缀名是.def),把其加入到工程中,输入以下信息:
LIBRARY Dll2

EXPORTS
add
sub
此时编译生产出来的DLL里的add和sub函数就不是乱码名字了!

情况五:怎么动态调用DLL(显式调用)

首先在主程序的目录下放置需要调用的DLL文件,然后在主程序中:

HINSTANCE hInst;
hInst 
= LoadLibrary("Dll2.dll");
typedef 
int (*ADDPROC)(int a, int b);
ADDPROC Add 
= (ADDPROC)GetProcAddress(hInst, "add");
if(!Add)
 MessageBox(
"获取函数地址失败!");
 
return;
int result = Add(5,3);

 

情况六:DLL中 的函数调用约定是标准调用时(也即pascal调用约定),主程序该怎么写?

此时在DLL中就应该是这样的:

int _stdcall add(int a, int b)
{
 
return a+b;
}

int _stdcall sub(int a, int b)
{
 
return a-b;
}

 

主程序中:

HINSTANCE hInst;
hInst 
= LoadLibrary("Dll2.dll");
typedef 
int (_stdcall *ADDPROC)(int a, int b);
ADDPROC Add 
= (ADDPROC)GetProcAddress(hInst, "add");
if(!Add)
 MessageBox(
"获取函数地址失败!");
 
return;
int result = Add(5,3);

 

 

 

posted @ 2009-11-18 13:39  小试锋芒  阅读(423)  评论(0编辑  收藏  举报