即使库链接,DLL 也会被忽略

Posted

技术标签:

【中文标题】即使库链接,DLL 也会被忽略【英文标题】:DLL silently ignored even though the library links 【发布时间】:2020-07-09 18:02:30 【问题描述】:

我正在使用已成功使用多年的第三方 DLL。现在链接器毫无问题地链接了 dll 库,但 exe 没有加载 dll。

我最近从 32 位升级到 64 位 cygwin。 我正在将 mingw 交叉编译为 32 位。 我正在尝试使用 FTDI USB 接口 FTD2XX dll。

我有版本 2.04.06 FTD2XX lib、.h 和 dll。 我多年来一直在成功使用该 dll,但使用的是旧版本的 cygwin 和 mingw。 最近升级到cygwin64。

该应用似乎毫无怨言地与 FTD2XX.lib 链接。 但是当我运行该应用程序时,它似乎并没有寻找或加载 FTD2XX.dll。 该应用程序运行但一旦尝试调用 FTD2XX dll 中的某些内容就会崩溃。

我为并行测试创建了一个简单的 hello_dll.dll。这样可行。 app.c 调用 hello_dll.dll 和 ftd2xx.dll。 启动时没有报错,成功调用 hello_dll 中的函数,然后在调用 ft2xx.dll 时崩溃。

(我将 lib 重命名为 ftd2xx_2.04.06 以将它们与我拥有的其他版本区分开来。新版本不能更好地工作。)

与 -verbose 的链接给出:

i686-w64-mingw32-gcc -Wall -m32 -g -O2 -c -I . -o app.o app.c
i686-w64-mingw32-gcc -Wall -m32 -o app.exe app.o -Wl,-verbose -L. -lhello_dll -lftd2xx_2.04.06
GNU ld (GNU Binutils) 2.34.50.20200227
  Supported emulations:
   i386pe
using internal linker script:

<snip>

/usr/lib/gcc/i686-w64-mingw32/9.2.0/../../../../i686-w64-mingw32/bin/ld: mode i386pe
attempt to open /usr/i686-w64-mingw32/sys-root/mingw/lib/../lib/crt2.o succeeded
/usr/i686-w64-mingw32/sys-root/mingw/lib/../lib/crt2.o
attempt to open /usr/lib/gcc/i686-w64-mingw32/9.2.0/crtbegin.o succeeded
/usr/lib/gcc/i686-w64-mingw32/9.2.0/crtbegin.o
attempt to open app.o succeeded
app.o

<snip>

attempt to open ./hello_dll.lib succeeded
./hello_dll.lib
(./hello_dll.lib)d000001.o
(./hello_dll.lib)d000000.o
(./hello_dll.lib)d000002.o

<snip>

attempt to open ./ftd2xx_2.04.06.lib succeeded
./ftd2xx_2.04.06.lib
(./ftd2xx_2.04.06.lib)FTD2XX.dll
(./ftd2xx_2.04.06.lib)FTD2XX.dll
(./ftd2xx_2.04.06.lib)FTD2XX.dll
(./ftd2xx_2.04.06.lib)FTD2XX.dll

::::::::::::::::::::::::::::

我获得了一个 32 位兼容版本的 gdb。当我运行 gdb 时:

GNU gdb (GDB) 7.7.50.20140303-cvs
<snip>
This GDB was configured as "i686-pc-mingw32".
<snip>
(gdb) break main
(gdb) Breakpoint 1 at 0x40267b: file app.c, line 28.
(gdb) run
(gdb) Starting program: C:\_d\aaa\pd\src\dll\pathological\app.exe
[New Thread 1428.0x2528]

Breakpoint 1, main (argc=1, argv=0x9b2f70) at app.c:28
28              dostuff();

(gdb) info share
(gdb) From        To          Syms Read   Shared Object Library
0x774e0000  0x77644ccc  Yes (*)     C:\Windows\SysWOW64\ntdll.dll
0x753d0000  0x754cadec  Yes (*)     C:\Windows\syswow64\kernel32.dll
0x75ea1000  0x75ee6a3a  Yes (*)     C:\Windows\syswow64\KernelBase.dll
0x64081000  0x6408a1d8  Yes         C:\_d\aaa\pd\src\dll\pathological\hello_dll.dll
0x75041000  0x750eb2c4  Yes (*)     C:\Windows\syswow64\msvcrt.dll
(*): Shared library is missing debugging information.
(gdb) A debugging session is active.

(gdb) c
Continuing.
Hello dll.             <--- The function in hello_dll.dll prints this.


Program received signal SIGSEGV, Segmentation fault.
0x8000004c in ?? ()                        <----- call to FT_GetLibraryVersion()

(gdb) bt
#0  0x8000004c in ?? ()
#1  0x0040158e in dostuff () at app.c:49
#2  0x00402680 in main (argc=1, argv=0x8e2f70) at app.c:28
(gdb)

它毫无怨言地与 lib 链接,但是当我运行 exe 时,它​​(静默)不加载 dll。

有人有什么想法吗?是否有一些我缺少的链接器控件?是否有其他诊断或调试工具可以进一步深入研究?

::::::::::::::::::::::::

编辑 7/11/20

我会发布一些代码。 (如果我知道怎么做的话。我是新来的。)

它应该显示在“信息共享”中,但事实并非如此,正如您在上面看到的那样。

我怀疑名字装饰。 .exe 的 Objdump -x 在导入表中显示 FTD2XX.dll 的条目。但它没有在它下面显示任何 vma 或绑定名称。我怀疑在程序加载时加载程序看不到 vma/name 并决定它并不真的需要加载 dll。

.idata 中 0x406000 处有一个导入表

<snip>

The Import Tables (interpreted .idata section contents)
 vma:            Hint    Time      Forward  DLL       First
                 Table   Stamp     Chain    Name      Thunk
 00006000   0000607c 00000000 00000000 00006218 0000614c

    DLL Name: FTD2XX.dll
    vma:  Hint/Ord Member-Name Bound-To
                                                      <----- empty?

 00006014   00006080 00000000 00000000 000064f8 00006150

    DLL Name: hello_dll.dll
    vma:  Hint/Ord Member-Name Bound-To
    6224        1  hello_dll

 00006028   00006088 00000000 00000000 00006554 00006158

    DLL Name: KERNEL32.dll
    vma:  Hint/Ord Member-Name Bound-To
    6230      277  DeleteCriticalSection
    6248      310  EnterCriticalSection

<snip>

::::::::::::::::::::::::::::::::::::::::::::

编辑 2,2020 年 7 月 11 日

这是调用 DLL 中的函数的程序。

/* app.c

   Demonstrates using the function imported from the DLL.
*/

// 200708 pathological case. Based on the simple hello_dll.

//#include <stdlib.h>
// for sleep
#include <unistd.h>
#include <stdio.h>
// for dword
#include <windef.h>
// for lpoverlapped
#include <minwinbase.h>

#include "hello_dll.h"
// My legacy app, and really all others too, use 2.04.06.h
#include "ftd2xx_2.04.06.h"
//#include "ftd2xx_2.02.04.h"

///////////////////////////

void dostuff( void );
void call_ft_listdevices( void );

///////////////////////////

int main(int argc, char** argv)

    FT_STATUS status;
    DWORD libver;

    //dostuff();

    printf( "Calling hello_dll():\n" );
    fflush( stdout );
    hello_dll();
    fflush( stdout );
    printf( "Back from hello_dll()\n" );
    fflush( stdout );

    sleep( 1 );

    printf( "Calling FT_GetLibraryVersion().\n" );
    fflush( stdout );

    status = FT_GetLibraryVersion( &libver );
    if( status == FT_OK )
        printf( "FTD2XX library version 0x%lx\n", libver );
        fflush( stdout );
    
    else
        printf( "Error reading FTD2XX library version.\n" );
        fflush( stdout );
    

    // 200710 Adding call to different ft function did
    // not result in entries in the import table.
    //call_ft_listdevices( );

    return 0;

我认为不需要包含我的 hello_dll 的代码。它有效。

我有三个版本的 FTD2XX。我对跟踪版本非常小心。另外,当一个人头疼不已时,尽早仔细检查版本是一种结束痛苦的方法。

我意外地发现了 FTD2XX.dll 的副本。它在 c:/Windows/SysWOW64 中。它是我拥有的三个版本中最古老的一个。在此问题开始之前编译的我的应用程序版本在该位置使用该 dll 正确运行。

【问题讨论】:

很难说没有看到任何实际代码,但如果你真的使用 dll 中的 FT_* 函数,那么 dll 应该显示为info shared 根据个人经验,我建议将 FT dll 重命名为 32 和 64,以避免混淆。如果您使用 FTDI 提供的最新 dll 会怎样? 我已经编辑了帖子以包含调用 dll 的主程序的代码。不要认为我需要发布我的 hello_dll 代码。有用。 - 它应该显示在共享的信息中,但它没有。我开始怀疑名字装饰了。 你可以打赌我很早就检查了版本,并在它绘制时仔细检查了。--我有三个版本。我一直在使用 32 位版本。 在另一台装有 Mingw 5.4.0 的计算机上编译并运行良好。不适用于装有 Mingw 9.2.0 的主计算机。将 5.4.0 链接器复制到主计算机。作品。这本身不是解决方案。我不想在我的主计算机上完全恢复到 5.4.0。但显然,Mingw 发生了一些变化。 【参考方案1】:

解决了。

2.34.50.20200227 i686-w64-mingw32-ld.exe 中有一个错误。据我所知,无论 ftd2xx 版本如何,它都不适用于 ftd2xx.lib。

2.25.51.20150320 和 2.29.1.20171006 与 ftd2xx.lib 一起使用。我已经恢复到 2.29 mingw64-i686-binutils。我又跑了。

【讨论】:

sourceware.org/bugzilla/show_bug.cgi?id=25374 有一个错误报告和一个 python 脚本来转换 MSVC lib,但还没有尝试过

以上是关于即使库链接,DLL 也会被忽略的主要内容,如果未能解决你的问题,请参考以下文章

为啥即使禁用缓存,服务器也会忽略代码文件中的更改?

Postgres 忽略表约束,即使约束不匹配也会扫描所有继承的表

即使在连接字符串中使用 HDR=No ,使用 OLEDB 读取 CSV 文件也会忽略第一行

gcc -nostdlib是否会阻止标准库的显式附加?

Visual Studio 2017 动态链接库(DLL /LIB) 静态链接库(LIB)的思考

光晕2问啥我登不进一直出现:光晕2 无法定位序数2于动态链接库ADVAPI32.dll上