本文亮点:无需使用反射,无需动态生成方法,无需CallWindowProc!
本文毒点:如果你不知道要调用的API函数原型(函数名、参数类型、返回值类型),本文不能帮助你,建议关注API Monitor、反向工程等话题。
静态加载
所谓静态加载,是指你在编码时就知道DLL文件的位置,用户有义务保证运行时可以在那个固定的、不允许变更的位置找到DLL文件。这种情况可以使用简单的静态调用。
静态调用十分简单,官网文档就有详解,但是出于完整性考虑还是在这里解说一下。
Imports System.Runtime.InteropServices
'方法1:使用Declare语句声明调用kernel32.dll中的LoadLibraryW函数,该函数接受一个LPWStr类型的String参数,返回一个IntPtr
Declare Function LoadLibraryW Lib "kernel32.dll" (<MarshalAs(UnmanagedType.LPWStr)> Dll路径 As String) As IntPtr
'方法2:使用DllImport特性声明调用kernel32.dll中的GetProcAddress函数,该函数在本程序集中被改名为Fg_InitLibrariesExGpa,接受一个IntPtr和一个String参数,返回IntPtr
<DllImport("kernel32.dll", BestFitMapping:=False, EntryPoint:="GetProcAddress")> Function Fg_InitLibrariesExGpa(Dll指针 As IntPtr, Api名称 As String) As IntPtr
End Function
最典型的两种静态加载调用的方法:
- Declare Function/Sub 函数名 Lib DLL路径 Alias 入口点 (参数列表) As 返回类型。如果指定Sub则必须去掉As 返回类型。这是一种比较简单的声明方法,但是无法实现某些特殊功能。如果在Public类或模块中声明,应当加上Private访问限制。如果参数列表中有String,应当用MarshalAs特性注明函数原型接受的是LPWStr还是LPStr。参数类型是重要的,参数名称可以任意。如果你声明的函数名就是其原名,Alias 入口点可以省略。
- <DllImport(DLL路径, 其它属性列表)>一般的函数声明。这是一种复杂的声明方法,可以实现一些高级功能。例子中指定了BestFitMapping字段