即使库链接,DLL 也会被忽略
DLL silently ignored even though the library links
我正在使用我已经成功使用多年的第三方 DLL。现在 linker links 没有抱怨的 dll 库但是 exe 没有加载 dll。
我最近从 32 位升级到 64 位 cygwin。
我正在将 mingw 交叉编译为 32 位。
我正在尝试使用 FTDI USB 接口 FTD2XX dll。
我有版本 2.04.06 FTD2XX lib、.h 和 dll。
我多年来一直成功地使用该 dll,但使用的是旧版本的 cygwin 和 mingw。
最近升级到 cygwin64.
该应用似乎 link FTD2XX.lib 没有投诉。
但是当我 运行 应用程序时,它似乎没有寻找或加载 FTD2XX.dll。
该应用程序 运行s 但在它尝试调用 FTD2XX dll 中的内容时立即崩溃。
我创建了一个简单的 hello_dll.dll 用于并排测试。这样可行。
app.c 调用 hello_dll.dll 和 ftd2xx.dll。
开始时没有抱怨,成功调用 hello_dll 中的函数,然后在调用 ft2xx.dll.
时崩溃
(我将 lib 重命名为 ftd2xx_2.04.06,以区别于我拥有的其他版本。较新的版本并没有更好的效果。)
Link 与 -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
::::::::::::::::::::::::::::
我获得了 gdb 的 32 位兼容版本。当我 运行 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)
它 link 与 lib 毫无怨言,但是当我 运行 exe 它(默默地)不加载 dll。
有人有什么想法吗?是否缺少某些 linker 控件?是否有其他诊断或调试工具可以进一步深入研究?
::::::::::::::::::::::::
编辑 2020 年 7 月 11 日
我会 post 一些代码。 (如果我知道怎么做的话。我是新来的。)
它应该显示在“信息共享”中,但实际上并没有,正如您在上面看到的那样。
我怀疑名字修饰。 .exe 的 Objdump -x 在导入表中显示 FTD2XX.dll 的条目。但是它下面没有显示任何 vma 或绑定名称。我怀疑在程序加载时,加载程序看不到 vma/name 并决定它真的不需要加载 dll。
在 0x406000
的 .idata 中有一个导入 table
<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。
已解决。
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。我又是运行了。
我正在使用我已经成功使用多年的第三方 DLL。现在 linker links 没有抱怨的 dll 库但是 exe 没有加载 dll。
我最近从 32 位升级到 64 位 cygwin。 我正在将 mingw 交叉编译为 32 位。 我正在尝试使用 FTDI USB 接口 FTD2XX dll。
我有版本 2.04.06 FTD2XX lib、.h 和 dll。 我多年来一直成功地使用该 dll,但使用的是旧版本的 cygwin 和 mingw。 最近升级到 cygwin64.
该应用似乎 link FTD2XX.lib 没有投诉。 但是当我 运行 应用程序时,它似乎没有寻找或加载 FTD2XX.dll。 该应用程序 运行s 但在它尝试调用 FTD2XX dll 中的内容时立即崩溃。
我创建了一个简单的 hello_dll.dll 用于并排测试。这样可行。 app.c 调用 hello_dll.dll 和 ftd2xx.dll。 开始时没有抱怨,成功调用 hello_dll 中的函数,然后在调用 ft2xx.dll.
时崩溃(我将 lib 重命名为 ftd2xx_2.04.06,以区别于我拥有的其他版本。较新的版本并没有更好的效果。)
Link 与 -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
::::::::::::::::::::::::::::
我获得了 gdb 的 32 位兼容版本。当我 运行 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)
它 link 与 lib 毫无怨言,但是当我 运行 exe 它(默默地)不加载 dll。
有人有什么想法吗?是否缺少某些 linker 控件?是否有其他诊断或调试工具可以进一步深入研究?
::::::::::::::::::::::::
编辑 2020 年 7 月 11 日
我会 post 一些代码。 (如果我知道怎么做的话。我是新来的。)
它应该显示在“信息共享”中,但实际上并没有,正如您在上面看到的那样。
我怀疑名字修饰。 .exe 的 Objdump -x 在导入表中显示 FTD2XX.dll 的条目。但是它下面没有显示任何 vma 或绑定名称。我怀疑在程序加载时,加载程序看不到 vma/name 并决定它真的不需要加载 dll。
在 0x406000
的 .idata 中有一个导入 table<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。
已解决。
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。我又是运行了。