关于MinGW下.dll.a文件的作用

12 篇文章 0 订阅

 

.dll.a文件的最初用意其实是MinGW下的DLL文件的imp-lib,即与VC下DLL文件附带了一个引入库.lib类似。在VC下编程,当要使用DLL文件时,在开发时必须要有.lib文件才能链接通过。.dll.a文件就是这样的作用。

 

但是,MinGW/Cygwin确提供了直接与.dll文件链接的作用,就是可以不需要imp-lib库文件,只要DLL文件存在,也可以链接成功。这样就导致.dll.a文件似乎不是那么有用了。在很多场合下,可以不需要.dll.a文件了。但是有几个例外情况,来自于RedHat的官方描述。

 

 

5.8. ld and WIN32 (cygwin/mingw)

http://www.redhat.com/docs/manuals/enterprise/RHEL-4-Manual/gnu-linker/win32.html

 

 

 

direct linking to a dll

The cygwin/mingw ports of ld support the direct linking, including data symbols, to a dll without the usage of any import libraries. This is much faster and uses much less memory than does the traditional import library method, expecially when linking large libraries or applications. When ld creates an import lib, each function or variable exported from the dll is stored in its own bfd, even though a single bfd could contain many exports. The overhead involved in storing, loading, and processing so many bfd's is quite large, and explains the tremendous time, memory, and storage needed to link against particularly large or complex libraries when using import libs.

Linking directly to a dll uses no extra command-line switches other than -L and -l, because ld already searches for a number of names to match each library. All that is needed from the developer's perspective is an understanding of this search, in order to force ld to select the dll instead of an import library.

For instance, when ld is called with the argument -lxxx it will attempt to find, in the first directory of its search path,

libxxx.dll.a
xxx.dll.a
libxxx.a
cygxxx.dll (*)
libxxx.dll
xxx.dll

before moving on to the next directory in the search path.

(*) Actually, this is not cygxxx.dll but in fact is <prefix>xxx.dll, where <prefix> is set by the ld option -dll-search-prefix=<prefix>. In the case of cygwin, the standard gcc spec file includes -dll-search-prefix=cyg, so in effect we actually search for cygxxx.dll.

Other win32-based unix environments, such as mingw or pw32, may use other <prefix>es, although at present only cygwin makes use of this feature. It was originally intended to help avoid name conflicts among dll's built for the various win32/un*x environments, so that (for example) two versions of a zlib dll could coexist on the same machine.

The generic cygwin/mingw path layout uses a bin directory for applications and dll's and a lib directory for the import libraries (using cygwin nomenclature):

bin/
	cygxxx.dll
lib/
	libxxx.dll.a   (in case of dll's)
	libxxx.a       (in case of static archive)

Linking directly to a dll without using the import library can be done two ways:

1. Use the dll directly by adding the bin path to the link line

gcc -Wl,-verbose  -o a.exe -L../bin/ -lxxx

However, as the dll's often have version numbers appended to their names (cygncurses-5.dll) this will often fail, unless one specifies -L../bin -lncurses-5 to include the version. Import libs are generally not versioned, and do not have this difficulty.

2. Create a symbolic link from the dll to a file in the lib directory according to the above mentioned search pattern. This should be used to avoid unwanted changes in the tools needed for making the app/dll.

ln -s bin/cygxxx.dll lib/[cyg|lib|]xxx.dll[.a]

Then you can link without any make environment changes.

gcc -Wl,-verbose  -o a.exe -L../lib/ -lxxx

This technique also avoids the version number problems, because the following is perfectly legal

bin/
	cygxxx-5.dll
lib/
	libxxx.dll.a -> ../bin/cygxxx-5.dll

Linking directly to a dll without using an import lib will work even when auto-import features are exercised, and even when -enable-runtime-pseudo-relocs is used.

Given the improvements in speed and memory usage, one might justifiably wonder why import libraries are used at all. There are two reasons:

1. Until recently, the link-directly-to-dll functionality did not work with auto-imported data.

2. Sometimes it is necessary to include pure static objects within the import library (which otherwise contains only bfd's for indirection symbols that point to the exports of a dll). Again, the import lib for the cygwin kernel makes use of this ability, and it is not possible to do this without an import lib.

So, import libs are not going away. But the ability to replace true import libs with a simple symbolic link to (or a copy of) a dll, in most cases, is a useful addition to the suite of tools binutils makes available to the win32 developer. Given the massive improvements in memory requirements during linking, storage requirements, and linking speed, we expect that many developers will soon begin to use this feature whenever possible.

 

 

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MSVC vs. MinGW 之 (lib,dll,def,obj,exe) vs (a,dll,def,o,exe) 玩转攻略手记 一份粗糙的研究记录,有待补完和整理。 MinGW: c -> o gcc -c a.c c -> exe gcc a.c libs.o -o a.exe (从主程序a.c,附加libs,生成a.exe) o -> exe gcc a.o b.o ... -o main.exe c -> dll,def,a gcc a.c -shared -o a.dll -Wl,--output-def,a.def,--out-implib,liba.a a -> dll a2dll liba.a dll -> a: dlltool --dllname a.dll --def a.def --output-lib liba.a (需要def文件) a -> def: dumpbin /exports lib.a > lib.def (在windows上调用,def需要修改) dll -> def : pexports a.dll -o > a.def (这里的-o是指给函数标序号) lib -> def : reimp -d a.lib lib -> a: (for __cdecl functions in most case) reimp a.lib; (for __stdcall functions) MSVC: c -> lib cl /LD a.c (注意已经定义了export列表) c -> dll cl /LD a.c c -> obj cl /c a.c c -> exe cl a.c /out:a.exe dll ->lib lib /machine:ix86 /def:a.def /out:a.lib (需要def文件) obj ->lib lib a.obj b.obj... /out:mylib.lib dll ->def DUMPBIN a.dll /EXPORTS /OUT:a.def (生成的def需要做修正) lib ->def reimp -d a.lib (这个要在MSYS+MinGW下用) 关于这些工具的适用范围可以很容易的理解和记忆。 dll和exe都是PE文件,所以可以使用pexports. lib和a是静态库文件,都是归档类型,不是PE格式。所以不能使用pexports. dll可以使用dlltool. lib可以使用lib, 和reimp(lib->a工具) 所有的bin文件,包括dll,exe,lib,a都可以使用dumpbin. 参考: http://hi.baidu.com/kaien_space/blog/item/5e77fafa2ba9ff16a8d3110a.html Mingw官网文档: http://www.mingw.org/wiki/MSVC_and_MinGW_DLLs http://oldwiki.mingw.org/index.php/CreateImportLibraries http://www.mingw.org/wiki/FAQ http://hi.baidu.com/opaquefog/blog/item/9b21b6deb324e25dccbf1ab7.html http://qzone.qq.com/blog/8330936-1238659272 http://hi.baidu.com/jzinfo/blog/item/b0aa1d308de99f9da8018e00.html 本篇测试用代码: 1. main.cpp #include #include #include "mylib.h" using namespace std; int main() { char str[]="Hello world!"; printhello(str); return 0; } 2. mylib.cpp #include #include #include "mylib.h" using namespace std; void EXPORT printhello(char *str) { cout << str << endl; } 3. mylib.h #define EXPORT __declspec(

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值