动态链接库(DLL)创建及使用

1.创建一个动态链接库

l         使用VC6新创建一个“Win32 Dynamic Application”工程,名称为“testdll”,创建类型为“一个空的DLL项目工程”;

l         在菜单“工程”中的“增加到工程”中选择“文件”,为该工程添加一个存在的testdll.cpp文件,testdll.cpp内容如下:

#define DLLEXPORT  __declspec( dllexport )

extern "C" DLLEXPORT

void sum(int x,int y,int *z)

{

       *z = x+y;

}

 

extern "C" DLLEXPORT

int prod(int x,int y)

{

       return x*y;

}

按“F7”编译该工程,在debug 目录下会得到一个静态库“testdll.lib”和一个动态库“testdll.dll”文件;

2.使用动态库

隐式链接使用动态库:

在任意一个目录新建内一个名为“testapp.cpp”文件,内容如下:

#include <stdio.h>

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

void sum(int x,int y,int *z);

int prod(int x,int y);

void main()

{

       int z=0;

       sum(8,7,&z);

       printf("sum=%d/n",z);

       printf("prod=%d",prod(3,4));

}

该文件保存好后使用一个新的VC6打开,然后按“F7”编译,系统会提示为该文件创建一个工程,按“确定”会得到“testapp”工程;

将刚刚创建的“testdll.lib”和“testdll.dll”两个文件放置新生成“testapp”的目录下,在VC环境里按“Ctrl+F 5 会看到运行的结果

显示链接使用动态库:

显示链接在编译时不需要链接lib库文件,也无需为该库的头文件。

按上述创建隐式链接的方法新创建一个空的文件“testapp2.cpp”,内容如下:

 

#include <windows.h>

#include <stdio.h>

 

typedef void (*SUM_PROC)(int,int,int *);

typedef int (*PROD_PROC)(int,int);

void main()

{

       HMODULE hm=LoadLibrary("testdll.dll");

       SUM_PROC sum = (SUM_PROC)GetProcAddress(hm,"sum");;

       int z=0;

       sum(56,9,&z);

 

       PROD_PROC prod=(PROD_PROC)GetProcAddress(hm,"prod");

       prod(4,8);

 

       FreeLibrary( hm );

}

只将“testdll.dll”拷贝至该应用程序的目录下,编译并运行可看到结果。

3.注意事项:

l         无论是库文件,还是应用程序文件,文件的扩展名很重要,一般选择.cpp,这会按C++规则编译并链接生成,若使用.c扩展名则按C规则编译生成;

l         库文件的函数的前面加的extern "C"是必须的,它的功能是:该库不仅仅可为C++应用程序所使用,也可以为C应用程序使用;

l         生成库或应用程序的函数调用规则(在“工程”->“设置”的“C++”页面,分类选“Code Generation”后看到的“Calling convention”),按默认的“ __cdecl * 设置;

l         如果在应用程序的debug版本调用动态库出现__chkesp错,原因是应用程序在调用库函数前检查得到ESP指针和函数调用后的不一致而报错,仅编译debug版本可以将/GZ选项去掉即可;

l         动态库生成还可以使用def描述输出库函数文件方式获得,如上述的def文件描述为:

LIBRARY   TESTDLL

EXETYPE   WINDOWS

CODE      PRELOAD MOVEABLE DISCARDABLE

DATA      PRELOAD MOVEABLE SINGLE

EXPORTS

       sum @1

       prod @2

将该文件一同加入到库的工程中,并去掉导出关键字__declspec( dllexport )

l         应用程序为C规则的调用方式还有一种,如下程序:

void main()

{

       HMODULE hm=LoadLibrary("user32.dll");

       FARPROC fun;

 

       fun=GetProcAddress(hm,"MessageBoxA");

       fun(NULL,"hello","hello",MB_OK);

}

上述程序是可通过编译并正确执行的,根据试验,__declspec( dllexport )是不能得到的,而是将库函数前加extern int far pascal ,并添加导出描述文件def生成的;

l         动态库文件可用VC++的工具:Depends 查看该库的函数描述,若发现函数名不是你源文件中的函数名,例如添加了一些?@之类,说明该库在编译规则上不合适,需调整,重点检查该库的文件扩展名、有无extern “C”、及函数的调用规则。

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(C++,application,dll,pascal,fun,generation)