1. 程式人生 > WINDOWS開發 >C#中動態呼叫DLL動態連結庫

C#中動態呼叫DLL動態連結庫

原文:C#中動態呼叫DLL動態連結庫

其中要使用兩個未公開的Win32 API函式來存取控制檯視窗,這就需要使用動態呼叫的方法,動態呼叫中使用的Windows API函式主要有三個,即:Loadlibrary,GetProcAddress和Freelibrary。步驟如下:

1. Loadlibrary: 裝載指定DLL動態庫

2. GetProcAddress:獲得函式的入口地址

3. Freelibrary: 從記憶體中解除安裝動態庫

但是C#中是沒有函式指標,無法直接使用GetProcAddress返回的入口地址。後來找到資料,其實.NET 2.0新增了Marshal.GetDelegateForFunctionPointer 方法可以滿足這個要求,MSDN裡的解釋是:將非託管函式指標轉換為委託。

後面的事就簡單啦,我把它編成了一個類來方便呼叫。

技術分享圖片
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace feiyun0112.cnblogs.com
{
    public class DllInvoke
    {

        Win API#region Win API
        [DllImport("kernel32.dll")]
        private extern
static IntPtr LoadLibrary(string path); [DllImport("kernel32.dll")] private extern static IntPtr GetProcAddress(IntPtr lib,string funcName); [DllImport("kernel32.dll")] private extern static bool FreeLibrary(IntPtr lib); #endregion private
IntPtr hLib; public DllInvoke(String DLLPath) { hLib = LoadLibrary(DLLPath); } ~DllInvoke() { FreeLibrary(hLib); } //將要執行的函式轉換為委託 public Delegate Invoke (string APIName,Type t) { IntPtr api = GetProcAddress(hLib,APIName); return (Delegate)Marshal.GetDelegateForFunctionPointer(api,t); } } }
技術分享圖片

下面是使用程式碼

技術分享圖片
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using feiyun0112.cnblogs.com;

namespace ConsoleApplication1
{
    class Program
    {

        public delegate string Test(string a);

        static void Main(string[] args)
        {
            DllInvoke dll = new DllInvoke("test2.dll");
            Test test = (Test)dll.Invoke("testC",typeof(Test));
            string s = test("ss");
            Console.WriteLine(s);

            Console.WriteLine("****************************************");
            Console.ReadLine();
           
        }
    }
}
技術分享圖片

DllImport會按照順序自動去尋找的地方:
1、exe所在目錄
2、System32目錄
3、環境變數目錄
所以只需要你把引用的DLL 拷貝到這三個目錄下 就可以不用寫路徑了