概述
在c语言的实际编程中,我们可以把完成某项功能的函数放在一个动态链接库里,然后提供给其他程序调用。动态库是一种不可执行的二进制程序文件,它允许程序共享执行特殊任务所必需的代码和其他资源。Windows平台上动态链接库的后缀名是”.dll”,Linux平台上的后缀名是“.so”。Linux上动态库一般是libxxx.so;相对于静态函数库,动态函数库在编译的时候并没有被编译进目标代码中,你的程序执行到相关函数时才调用该函数库里的相应函数,因此动态函数库所产生的可执行文件比较小。由于函数库没有被整合进你的程序,而是程序运行时动态的申请并调用,所以程序的运行环境中必须提供相应的库。动态函数库的改变并不影响你的程序,所以动态函数库的升级比较方便。
动态链接库的优点
复用性:DLL的编制与具体的编程语言以及编译器无关,不同语言编写的程序只要按照函数调用约定就可以调用同一个DLL函数。
可扩展性:DLL文件与EXE文件独立,只要接口不变,升级程序只需更新DLL文件不需要重新编译应用程序。
节省内存:如果多个应用程序使用同一个dll,该dll的页面只需要存入内存一次,所有的应用程序都可以共享它的页面,从而节省内存。
动态库开发及调用示例
下面我们使用DEV C++开发工具来简单讲解一下动态库的开发及调用。
1、开发动态库
打开DEV C++,点击文件->新建(K)->项目(X)...,依次按如图示操作,创建动态库项目。


工具向导将自动创建头文件和源码文件如下,如果想修改扩展动态库的功能,可以自行修改。
dll.h:
#ifndef _DLL_H_
#define _DLL_H_
#if BUILDING_DLL
#define DLLIMPORT __declspec(dllexport)
#else
#define DLLIMPORT __declspec(dllimport)
#endif
DLLIMPORT void HelloWorld();
#endif
dllmain.c:
/* Replace "dll.h" with the name of your header */
#include "dll.h"
#include <windows.h>
DLLIMPORT void HelloWorld()
{
MessageBox(0,"Hello World from DLL!\n","Hi",MB_ICONINFORMATION);
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
switch(fdwReason)
{
case DLL_PROCESS_ATTACH:
{
break;
}
case DLL_PROCESS_DETACH:
{
break;
}
case DLL_THREAD_ATTACH:
{
break;
}
case DLL_THREAD_DETACH:
{
break;
}
}
/* Return TRUE on success, FALSE on failure */
return TRUE;
}
2、编译动态库
按如图所示对动态库代码进行编译,默认将会在项目目录生成动态库文件,名称和项目名称相同,后缀为.dll。

3、动态库调用示例
打开DEV C++,点击文件->新建(K)->项目(X)...,依次按如图示操作,创建动态库项目。


工具向导将自动创建源码文件模板,我们根据需要修改代码,代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int main(int argc, char *argv[]) {
// 定义函数指针
typedef void (*FUNT)();
// 加载动态库
HINSTANCE Hint = LoadLibrary("javainvokedll.dll");
// 获取动态库函数句柄
FUNT HelloWorld = (FUNT)GetProcAddress(Hint, "HelloWorld");
// 动态库函数调用
HelloWorld();
printf("Dll invoke result ok");
// 卸载动态库
FreeLibrary(Hint);
return 0;
}
如此,动态库的调用代码就完成了,我们编译运行以后,效果如下:



完整代码请参考使用C语言实现动态库及调用测试代码

219

被折叠的 条评论
为什么被折叠?



