(1)调用LoadLibrary加载非托管DLL到内存中,并调用GetProcAddress 获得内存中非托管函数的指针。
(2) 为包含非托管函数地址的托管签名生成一个DllImport存根(stub)。
(3) 压入被调用方保存的寄存器。
(4)创建一个DllImport帧(frame),并将其压入到堆栈帧(stack frame)。
(5)如果分配了临时内存,则预置一个清除列表,以便调用完成后快速将内存释放掉。
(6)封送参数,封送操作可能会分配内存。
(7)将垃圾回收( Garbage Collection)模式从协作式(cooperative)改为抢占式(preemptive),以便垃圾回收可以在任何时间进行。
(8) 加载目标地址并对其进行调用。
(9) 如果设置了SetLastError,则调用 GetLastError并将其返回的结果存储到一个线程上,而该线程则是抽象存储在线程本地存储(Thread Local Storage)中。
(10) 将垃圾回收模式改回到协作式。
(11)如果 PreserveSig 为 false且非托管方法返回一个失败的 HRESULT,则抛出异常。
(12)如果没有异常被抛出,将out和 ref引用类型的参数回传(back propagate)。
(13)将栈指针寄存器(Extended Stack Pointer)恢复成初始值,以还原调用方弹出的参数。
理解了平台调用的原理和过程,能有助于理解和掌握动态平台调用的方法。