編程(Programming)是編定程序的中文簡稱,就是讓計算機(jī)代碼解決某個問題,對某個計算體系規(guī)定一定的運算方式,使計算體系按照該計算方式運行,并最終得到相應(yīng)結(jié)果的過程。為了使計算機(jī)能夠理解(understand)人的意圖,人類就必須將需解決的問題的思路、方法和手段通過計算機(jī)能夠理解的形式告訴計算機(jī),使得計算機(jī)能夠根據(jù)人的指令一步一步去工作,完成某種特定的任務(wù)。這種人和計算體系之間交流的過程就是編程。 有一網(wǎng)友在程序開發(fā)時寫了一個dll文件,然后調(diào)用時出現(xiàn)LoadLibrary失敗的情況,本小編通過網(wǎng)上搜集了一些有關(guān)LoadLibrary失敗的原因及解決方法,希望對有需要的朋友有所幫助。
 一、出現(xiàn)LoadLibrary失敗的原因 通常LoadLibrary失敗的原因大多是代碼書寫不規(guī)范,編寫dll文件一般不是很難,但關(guān)鍵是在寫dll的時候代碼不規(guī)范,這樣在調(diào)用時就有可可能出現(xiàn)這樣那樣的問題,出現(xiàn)LoadLibrary失敗也就不足為怪了,為了保證你使用正確的調(diào)用規(guī)范,要通知編譯器使用stdcall規(guī)范和/或使用在windows.h(及相關(guān)文件)中定義的常量,如WINAPI等。通常DLL的代碼如下:
WORD WINAPI vbShiftRight(WORD nValue, WORD nBits) { return (nValue >> nBits); } 下一步是與你在微軟文檔中讀到的內(nèi)容相反。你需要創(chuàng)建一個DEF文件。這是你防止輸出函數(shù)名不出現(xiàn)亂字符的唯一方式(如_vbShiftRight@1)。DEF文件的形式如下:
EXPORTS vbShiftRight
下一步是在VB中調(diào)用這個函數(shù),使用以下聲明: Declare Function vbShiftRight Lib "MYDLL.DLL" (ByVal nValue As Integer, ByVal nBits As Integer)
As Integer
Sub Test() Dim i As Integer i = vbShiftRight(4, 2) Debug.Assert i = 1 End Sub 如果你還想要更容易的方法從VB中調(diào)用,可以創(chuàng)建一個類型庫。為此你需要創(chuàng)建和編譯ODL(對象描述語言)文件。這個文件應(yīng)該包含如下內(nèi)容: module MyModule { [ helpstring("Shifts the bits of an integer to the right."), entry("vbShiftRight") ] short _stdcall vbShiftRight([in] short nValue, [in] short nBits); }; 當(dāng)VB加載DLL的類型庫時,函數(shù)名和參數(shù)將出現(xiàn)在VB的對象瀏覽器中。此外,如果用戶不輸入正確的參數(shù)類型,VB將有可能產(chǎn)生LoadLibrary失敗錯誤。 還有就是你最好用正確的方法調(diào)用dll,以下是我正常調(diào)用dll的函數(shù): typedef void __declspec(dllimport) StartQueryForm(TDispatchConnection*,TApplication*); StartQueryForm* query; char buf[256]; if (!GetSystemDirectory(buf,256)) { Application->MessageBox("讀取系統(tǒng)目錄錯誤","錯誤",MB_OK+MB_ICONERROR); return ; } AnsiString sCmd=AnsiString(buf)+"\\QueryEnh.dll";
HINSTANCE Package = LoadLibrary(sCmd.c_str()); if (Package) { try { query = (StartQueryForm *)GetProcAddress((HINSTANCE)Package, "_StartQueryForm"); if (query) { TDispatchConnection* conn=(MainForm->ConnectionWay==1 ? (TDispatchConnection*)MainForm->dcomConnect: (TDispatchConnection*)MainForm->sockConnect); query(conn,Application); } else { AnsiString str="加載函數(shù)失敗,失敗原因:\n\r"; str+=SysErrorMessage(GetLastError()); Application->MessageBox(str.c_str(),"錯誤",MB_OK+MB_ICONERROR); } } __finally { FreeLibrary(Package); } } else { AnsiString str="加載庫失敗,失敗原因:\n\r"; str+=SysErrorMessage(GetLastError()); Application->MessageBox(str.c_str(),"´íÎó",MB_OK+MB_ICONERROR);
二、出現(xiàn)LoadLibrary失敗解決辦法
方式一 采用LoadLibraryEx 若DLL不在調(diào)用方的同一目錄下,可以用LoadLibrary(L"DLL絕對路徑")加載。但若調(diào)用的DLL內(nèi)部又調(diào)用另外一個DLL,此時調(diào)用仍會失敗。解決辦法是用LoadLibraryEx: LoadLibraryEx("DLL絕對路徑", NULL, LOAD_WITH_ALTERED_SEARCH_PATH); 通過指定LOAD_WITH_ALTERED_SEARCH_PATH,讓系統(tǒng)DLL搜索順序從DLL所在目錄開始。
方式二 采用SetCurrentDir 跨目錄調(diào)用dll,你應(yīng)該這樣 1 用GetCurrentDir保存當(dāng)前的工作目錄 2 用SetCurrentDir將當(dāng)前的工作目錄,設(shè)置為你的DLL所在的路徑,需要使用絕對路徑 3 用LoadLibrary你的DLL 4 使用SetCurrentDir恢復(fù)到原來的工作路徑
使用編程語言寫的程序,由于每條指令都對應(yīng)計算機(jī)一個特定的基本動作,所以程序占用內(nèi)存少、執(zhí)行效率高。 |