2019年5月14日 星期二

在64位元環境下動態載入DLL



繼2011年發佈一篇文章
將非 COM 元件的外部 DLL ,包入 .NET 開發的執行檔中
直到現在又遇到問題了,趕緊寫下來記錄
本來專案都 Complier 成 x86,所以在64位元系統下仍然以 32位元在RUN,
但最近公司要求換成 AnyCPU,這下子就出問題了,

''原來的寫法,在64位元系統會取到 IntPtr 值為 0 的問題
    Friend Declare Function GetProcAddress Lib "kernel32" (ByVal ModuleHandle As Integer, ByVal ProcName As String) As Integer
    ''改成 IntPtr ,執行到 GetProcAddress 會有數學運算溢位的錯誤
    Friend Declare Function GetProcAddress Lib "kernel32" (ByVal ModuleHandle As Integer, ByVal ProcName As String) As IntPtr 
    

後來在
https://www.daniweb.com/programming/software-development/threads/207639/getprocaddress-and-function-pointers
的文章發現一個寫法,
    Friend Declare Function GetProcAddress Lib "kernel32" (ByVal ModuleHandle As IntPtr, <[In](), MarshalAs(UnmanagedType.LPStr)> ByVal lpProcName As String) As IntPtr


我一直以為在 64位元 GetProcAddress 回傳的值要改成 IntPtr,漏了傳入參數也要跟著換,
   '最後換成以下寫法就可以
   Friend Declare Function GetProcAddress Lib "kernel32" (ByVal ModuleHandle As IntPtr, ByVal ProcName As String) As IntPtr

換完後,好奇的我再試一下 x86 是否可以通用,
結果是可以的,再查了一下 IntPtr ,才發現這個元件根據 OS 的位元數,所回傳的值也會不同,
也就是從頭到尾只要統一用 IntPtr 就可以了,嗯~又學到一課了!