本文将有以下4个部分来讲如何使用g++编译调用dll的c++代码。
1.如何调用dll
2.动态链接和静态链接的区别
3.g++的编译参数以及如何编译调用dll的c++代码
4.总结
1.如何调用dll
动态链接库(Dynamic Link Library),简称DLL。DLL 是一个包含可由多个程序同时使用的代码和数据的库。它允许程序共享执行特殊任务所必需的代码和其他资源,一般来说,DLL是一种磁盘文件,以.dll、.DRV、.FON、.SYS和许多以.EXE为扩展名的系统文件都可以是DLL。它由全局数据、服务函数和资源组成,在运行时被系统加载到调用进程的虚拟空间中,成为调用进程的一部分。
DLL的调用可以分为两种:一种是隐式调用(需要.lib和.dll),一种是显示调用(需要.dll)。
1.1 隐式调用
隐式加载就是在程序编译的时候就将dll编译到可执行文件中。实现隐式链接只要将导入函数关键字_declspec(dllimport)函数名等写到应用程序相应的头文件中就可以了。下面将通过一个例子来讲解隐式链接调用Dlltest.dll库中的Min函数。
首先新建一个项目为TestDll,在Dlltest.h、Dlltest.cpp文件中分别输入如下代码:
Dlltest.h的代码如下:
//隐式加载Dlltest #pragma comment(lib,"Dlltest.lib") //声明外部函数 extern "C"_declspec(dllimport) int Max(int a,int b); extern "C"_declspec(dllimport) int Min(int a,int b);
Dlltest.cpp的代码如下:
#include<stdio.h>
#include"Dlltest.h"
int main()
{
int a;
a=Min(1,2);
printf("Min(1,2)result is %d\n",a);
return 0;
}
在生成Dlltest.exe文件之前,要先将Dlltest.dll和Dlltest.lib拷贝到debug同目录(工程根目录)下,也可以拷贝到windows的System目录下。如果DLL使用的是def文件,要删除Dlltest.h文件中关键字extern "C"。Dlltest.h文件中的关键字pragma commit是要Visual C++的编译器在link时,链接到Dlltest.lib文件。当然,开发人员也可以不使用#pragma comment(lib,"Dlltest.lib")语句,而直接在工程的Setting->Link页的Object/Moduls栏填入Dlltest.lib既可。
1.2 显式调用
显式加载是指在程序运行过程中,需要用到dll里的函数时,再动态加载dll到内存中,这种加载方式因为是在程序运行后再加载的,dll的维护更容易,使得程序如果需要更新,很多时候直接更新dll,而不用重新安装程序。使用这种方式使应用程序在执行过程中随时可以加载DLL文件,也可以随时卸载DLL文件。
下面讲一个通过显式链接调用DLL中的Max函数的例子。
#include <stdio.h>
#include <windows.h>
int main()
{
typedef int(*pMax)(int a,int b);
typedef int(*pMin)(int a,int b);
HINSTANCE hDLL;
int A;
PMax Max;
//动态加载Dlltest.dll文件
HDLL=LoadLibrary("Dlltest.dll");
Max=(pMax)GetProcAddress(hDLL,"Max");
A=Max(1,2);
Printf("result is %d\n",A);
//卸载Dlltest.dll文件;
FreeLibrary(hDLL);
}
在上例中使用类型定义关键字typedef,定义指向和DLL中相同的函数原型指针,然后通过LoadLibray()将DLL加载到当前的应用程序中并返回当前DLL文件的句柄,然后通过GetProcAddress()函数获取导入到应用程序中的函数指针,函数调用完毕后,使用FreeLibrary()卸载DLL文件。