今天为大家介绍的内容是loadlibrary加载dll失败(windows10装载dll文件出错)下面跟着小编看看详细内容吧。
如何解决加载dll文件时出现“LoadLibrary failed”问题?用户在开发程序时编写了一个dll文件,但是调用该dll文件时出错,提示“LoadLibrary failed with error126: 找不到指定的模块”。到底是怎么回事?下面我们来分析一下发生LoadLibrary失败的原因以及解决办法。
1.LoadLibrary失败的原因
通常LoadLibrary失败的原因是代码编写不规范。编写dll文件一般来说并不难,但关键是编写dll时代码不规范。这样调用的时候就可能出现此类问题,LoadLibrary失败。毫不奇怪,为了确保您使用正确的调用规范,您需要通知编译器使用stdcall 规范和/或使用windows.h(以及相关文件)中定义的常量,例如WINAPI 等。通常DLL的代码如下:
01WORD WINAPI vbShiftRight(WORD nValue, WORD nBits)
02{
03return(nValue nBits);
04}
复制代码WORD WINAPI vbShiftRight(WORD nValue, WORD nBits) { return (nValue nBits); }
下一步与您在Microsoft 文档中阅读的内容相反。您需要创建一个DEF 文件。这是防止输出函数名出现乱码(如_vbShiftRight@1)的唯一方法。 DEF文件的格式如下:
01出口
02vb右移
复制代码EXPORTS vbShiftRight
下一步是使用以下声明在VB 中调用该函数:
01声明函数vbShiftRight Lib 'MYDLL.DLL' (ByVal nValue As Integer,
02ByVal nBits 作为整数)
03作为整数
04子测试()
05Dim i 作为整数
06i=vbShiftRight(4, 2)
07调试.断言i=1
08结束子
复制代码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 调用更简单的方法,您可以创建一个类型库。为此,您需要创建并编译ODL(对象描述语言)文件。该文件应包含以下内容:
01模块我的模块{
02[
03helpstring('将整数的位向右移动。'),
04entry('vbShiftRight')
05]
06short _stdcall vbShiftRight([输入]短nValue,[输入]短nBits);
07};
复制代码module MyModule { [ helpstring('将整数的位向右移动。'), entry('vbShiftRight') ] Short _stdcall vbShiftRight([in]short nValue, [in]short nBits); };
当VB加载DLL的类型库时,函数名称和参数将出现在VB的对象浏览器中。另外,如果用户没有输入正确的参数类型,VB很可能会生成LoadLibrary失败错误。
另外,你最好以正确的方式调用dll。以下是我用来正常调用dll的函数:
01typedef void __declspec(dllimport) StartQueryForm(TDispatchConnection,TApplication);
02StartQueryForm查询;
03字符缓冲区[256];
04if (!GetSystemDirectory(buf,256)) {
05Application-MessageBox('读取系统目录时出错','错误',MB_OK+MB_ICONERROR);
06返回;
07}
08AnsiString sCmd=AnsiString(buf)+'\\QueryEnh.dll';
复制代码typedef void __declspec(dllimport) StartQueryForm(TDispatchConnection,TApplication); StartQueryForm查询;字符缓冲区[256]; if (!GetSystemDirectory(buf,256)) { Application-MessageBox('读取系统目录时出错','错误' ,MB_OK+MB_ICONERROR);返回; AnsiString sCmd=AnsiString(buf)+'\\QueryEnh.dll';
01HINSTANCE 包=LoadLibrary(sCmd.c_str());
02if(封装)
03{
04尝试{
05query=(StartQueryForm)GetProcAddress((HINSTANCE)Package, '_StartQueryForm');
06if(查询){
07TDispatchConnection conn=(MainForm-ConnectionWay==1?
08(TDispatchConnection)MainForm-dcomConnect:
09(TDispatchConnection)MainForm-sockConnect);
10查询(conn,应用程序);
11}
12否则{
13AnsiString str='加载函数失败,失败原因:\n\r';
14str+=SysErrorMessage(GetLastError());
15Application-MessageBox(str.c_str(),'错误',MB_OK+MB_ICONERROR);
16}
17}
18__终于{
19免费库(包);
20}
21}
22其他
23{
24AnsiString str='加载库失败,失败原因:\n\r';
25str+=SysErrorMessage(GetLastError());
26Application-MessageBox(str.c_str(),'′',MB_OK+MB_ICONERROR);
复制代码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);查询(conn,应用程序); } else { AnsiString str='加载函数失败,失败原因:\n\r'; str+=SysErrorMessage(GetLastError());应用程序消息框(str.c_str(),'错误',MB_OK+MB_ICONERROR); } } __finally { FreeLibrary(包); } } else { AnsiString str='加载库失败,失败原因:\n\r'; str+=SysErrorMessage(GetLastError()); Application-MessageBox(str.c_str(),'′',MB_OK+MB_ICONERROR);
2.LoadLibrary失败的解决方法
方法一:使用LoadLibraryEx
如果DLL与调用者不在同一目录中,可以使用LoadLibrary(L "DLL绝对路径")来加载它。但是,如果调用DLL调用另一个DLL,调用仍然会失败。
解决方案是使用LoadLibraryEx:
LoadLibraryEx('DLL绝对路径', NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
通过指定LOAD_WITH_ALTERED_SEARCH_PATH,系统DLL 搜索顺序从DLL 所在的目录开始。
方法2:使用SetCurrentDir
要跨目录调用dll,你应该这样做
1.使用GetCurrentDir保存当前工作目录
2. 使用SetCurrentDir 将当前工作目录设置为DLL 所在的路径。您需要使用绝对路径。
3.使用LoadLibrary加载你的DLL
4.使用SetCurrentDir恢复原来的工作路径
以上就是加载dll文件时提示“LoadLibrary failed”的原因及解决方法。如果遇到这个错误提示,可以参考上面的解决方法。
评论列表