http://blog.sina.com.cn/s/blog_4b3485000100w64p.html
先转过来 下来再看
目的:我们用vc写一个非常简单的AddTest.dll,它封装了一个sum函数,然后我们在另外一个程序中调用AddTest.dll.采用显示链接。
分析上面的程序我们可以看出,对Dll的调用分为一下几步:
首先,语句typedef int ( * lpAddFun)(int,int)定义了一个与add函数接受参数类型和返回值均相同的函数指针类型。随后,在main函数中定义了lpAddFun的实例addFun;
其次,在函数main中定义了一个DLL HINSTANCE句柄实例hDll,通过Win32 Api函数LoadLibrary动态加载了DLL模块并将DLL模块句柄赋给了hDll;
再次,在函数main中通过Win32 Api函数GetProcAddress得到了所加载DLL模块中函数add的地址并赋给了addFun。经由函数指针addFun进行了对DLL中add函数的调用;
最后,应用工程使用完DLL后,在函数main中通过Win32 Api函数FreeLibrary释放了已经加载的DLL模块。
在上面的例子中我们看到了由系统API提供的三位一体“DLL加载-DLL函数地址获取-DLL释放”方式,这种调用方式称为DLL的动态调用。
动态调用方式的特点是完全由编程者用 API 函数加载和卸载 DLL,程序员可以决定 DLL 文件何时加载或不加载,显式链接在运行时决定加载哪个 DLL 文件。
同样,还存在静态调用的方式。静态调用方式的特点是由编译系统完成对DLL的加载和应用程序结束时 DLL 的卸载。当调用某DLL的应用程序结束时,若系统中还有其它程序使用该 DLL,则Windows对DLL的应用记录减1,直到所有使用该DLL的程序都结束时才释放它。静态调用方式简单实用,但不如动态调用方式灵活。
下面我们来看看静态调用的例子,将编译dllTest工程所生成的.lib和.dll文件拷入dllCall工程所在的路径
#i nclude <iostream>
#i nclude <windows.h>
//---------1、动态调用类库--------------------------------------------
typedef int (_cdecl *DllAddMath)(int,int,int);
//2、静态调用类库
#pragma comment(lib,"AddTest.lib")
extern "C"__declspec(dllimport) int fun1(int x,int y);
int main()
{
//--1、动态调用类库---------由系统API提供的三位一体“DLL加载-DLL函数地址获取-DLL释放”方式,这种调用方式称为DLL的动态调用。
//2、静态调用类库
int result = fun1(2,3);
}
(三)在C#中调用
在引用中添加AddTest.dll
using AddTest;
private void button2_Click(object sender, EventArgs e)