C#網站呼叫C++非託管dll須知

iDotNetSpace發表於2009-05-06

今天在asp.net網站中呼叫C++非託管dll的時候到時候出現"法載入 DLL“dllTest.dll”: 找不到指定的模組。 (異常來自 HRESULT:0x8007007E)。 "的錯誤
我是把dll放在bin目錄下,後來放在與頁面同一級目錄下還是不行!這就讓我鬱悶了,因為以前在專案裡呼叫C++ Dll 就像呼叫API一樣把 DLL拷貝到System32下面,直接就
可以呼叫了,可現在做網站到時候是購買人家的空間不可能讓你去寫system32目錄的,仔細琢磨能不能根據相對路徑去呼叫C++ dll動態庫
,試了發多方法都不行,不過後來發現幾個要點:
1/ 指定絕對路徑是可能呼叫DLL裡面的方法,但最後你根本是不知道網站放哪個目錄,所以這個方法肯定不考慮
   [DllImport("D:\\dllTest.dll")]
2/ 如果用類庫(A)去呼叫 C++ DLL裡面方法,然後把該項類庫(A)的DLL和C++ DLL同時拷貝到網站bin目錄下,保持兩個DLL在同一路徑下,這樣也是可以的,但覺得就為了呼叫DLL
裡的幾個方法而專門寫個DLL去呼叫,也不合適!所以後面也沒考慮
3/ 還用種就是動態Load(Dll),就是先通過系統API動態去找到該 DDL元件,然後就再去呼叫裡面方法
   [DllImport("Kernel32.dll")]
        public static extern IntPtr LoadLibrary(string lpFileName);
 
        [DllImport("Kernel32.dll")]
        public static extern bool FreeLibrary(IntPtr hModule);
 
        [DllImport("Kernel32.dll")]
        public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);

        private IntPtr myDllHandle = IntPtr.Zero;

        public Delegate GetAddress(string functionName, Type t)
        {
            if (myDllHandle != IntPtr.Zero)
            {
                IntPtr functionAddr = GetProcAddress(myDllHandle, functionName);

                if (functionAddr == IntPtr.Zero)
                    return null;
                else
                    return Marshal.GetDelegateForFunctionPointer(functionAddr, t);
            }
            else
                return null;
        }

        public LoadDll(string dllFilePath)
        {
            myDllHandle = LoadLibrary(dllFilePath);
        }

        ~LoadDll()
        {
            if (myDllHandle != IntPtr.Zero)
            {
                FreeLibrary(myDllHandle);
            }
            myDllHandle = IntPtr.Zero;
        }

4/後來發現上面這些方法要麼不合理要麼太繁瑣,後面就發現一種方法可以
  把dllTest.dll拷貝到bin目錄下,然後釋出網站呼叫是可以的,因為釋出後的網站DLL都在bin目錄下與dllTest.dll同級所以是可以的
  但這種情況是如果直接到vs2005裡面除錯是不行的,因為除錯網站是在vs自帶的Web伺服器裡面執行的,利用的檔案是C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files
  這個目錄下的臨時檔案來執行的,但這裡沒有DLL所以除錯是達不到效果的
  不過後面有個重大發現就是:如果給網站加個解決方案(*.sln),保持testDll.dll和這個sln檔案在同一級目錄下,在vs2005除錯是可以的,但釋出後是不行的

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-594314/,如需轉載,請註明出處,否則將追究法律責任。

相關文章