您的当前位置:首页正文

DLL程序开发实例

2024-12-01 来源:个人技术集锦

 

             写在前面

DllDynamic Linkable Library的简称,是Windows系统下一种关键的程序运行方式。形式上,Dll是保存一些全局数据、函数、类等资源的文件,后缀名可以为.dll.fon.drv.sys.exe等等。

它自己不能运行,需要由应用程序来调用,也正因为这样,才促成了它的跨语言使用的特定:可以用某种语言编写一个Dll,然后用另一种语言调用,当然,这需要语言的支持。这种将数据和应用、函数库和应用程序的分离,使DllWin32平台上大显身手,一举成为Windows系统的主要调用方式,实际上,Windows中很多主要的函数都包括在Dll中,比如kernel.dll包含了内存管理、进程管理等函数,user32.dll包含了图形界面的相关函数,而gdi32.dll则包含了底层的画图及文本显示函数。

另外,Dll在内存中有唯一的映射,因此

下面首先通过一个简单实例来看看Dll是如何工作的。

   入门实例

VC程序写一个dll,再以另一个VC程序对其调用:

首先,建立一个Win32 Dynamic-Link Library类型的工程hellodll包含如下两个文件

1)  hellodll.h

#ifndef DLLEXPORT

#define DLLEXPORT extern "C" _declspec(dllimport)

#endif

 

DLLEXPORT int _stdcall add(int a,int b);

2)  hellodll.cpp

#include "hellodll.h"

#include <stdio.h>

 

int _stdcall add(int a,int b)

{

     return a+b;

}

VC中进行build得到Debug下的hellodll.dllhellodll.lib

建立另外一个普通工程hellodll_app,主程序如下:

3)  hellodll_app.cpp

#include <stdio.h>

#include <windows.h>

#include <iostream>

 

using namespace std;

typedef int (* AddFunc)(int a,int b);      // 1

int main(int argc,char *argv[])

{

int a=1,b=2,c;

AddFunc add;

HINSTANCE hInstLib = LoadLibrary("D://Program Files//Microsoft Visual Studio//MyProjects//hellodll//Debug//hellodll.dll");

 

if (hInstLib == NULL)

{

         cout<<"Dll failed to load." <<endl;

         FreeLibrary(hInstLib);

         system("pause");

         return 1;

 }

 

add = (AddFunc)GetProcAddress(hInstLib,"add");      // 2

if(!add)

{

        FreeLibrary(hInstLib);

        cout << "Dll Function add() got failed." << endl;

 

        return 1;

}

 

c = add(a,b);

FreeLibrary(hInstLib);

printf("add(%d,%d):%d/n",a,b,c);

 

return 0;

}

4)运行

一开始,运行提示"Dll Function add() got failed.",查看hellodll.lib,发现输出的API名字已经变成了_add@8,将注释//2处:

add = (AddFunc)GetProcAddress(hInstLib," add");

修改为:

add = (AddFunc)GetProcAddress(hInstLib,"_add@8");

故障解除。

又运行,出现错误The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

将注释//1处:

typedef int (* AddFunc)(int a,int b);

修改为:

typedef int (__stdcall * AddFunc)(int a,int b);

至此,运行正常。

 

那么,在第一个错误中,怎么能直接调用add函数呢?

答案是:去掉1) hellodll.h,添加 5) hellodll.def,如下:

5hellodll.def

LIBRARY hellodll

EXPORTS

add

当然,在hellodll.cpp中也要删除对hellodll.h#include

这样,编译链接生成hellodll.dll,那么在hellodll-app.cpp的注释//2处就可以使用

add = (AddFunc)GetProcAddress(hInstLib,"add");

得到dll接口函数了。

 

显示全文