1. 程式人生 > >VS編譯動態庫的時候沒有生成對應的lib檔案

VS編譯動態庫的時候沒有生成對應的lib檔案

}
   具體好像他們又有區別,希望知道的朋友能給解釋下,我也不是很清楚了,我當時就這麼用,然後我的問題搞定了,看了一些資料,也沒搞得很明白,具體有一段英文的好像寫的還比較明白了 一起貼下面了。

Stdcall and DLL tools of MSVC and MinGW

The __stdcall calling convention has been there for a very longtime. While older calling conventions like __pascal fell intooblivion, __stdcall became the standard calling convention of Win32API functions. Unlike __cdecl

(the native calling conventionof C/C++), it is supported in C/C++, Visual Basic, Java, and other languagesalike, which makes it the first choice when building a DLL for cross-languageuse.

The internal representations of both __cdecl and __stdcallfunctions have decorations. In MSVC (Microsoft Visual C++) and MinGW(Minimalistic GNU for Windows) GCC, __cdecl

function will be prefixedan underscore, and __stdcall functions will have the beginning underscoreas well as be appended by the at-sign (@) followed by the numberof bytes in the argument list. So,double __cdecl sin(double)will be decorated as _sin, and double __stdcall sin(double)will be decorated as
[email protected]
.

But things are not that simple. The decorations could change when theyappear in DLLs or when they are produced by different compilers. The followingtable lists the names as are produced by MSVC, MinGW, Digital Mars C/C++Compiler (DMC), Borland C++ Compiler/C++ Builder (BCC):
 

Calling Convention Internal* MSVC DLL (w/ DEF) MSVC DLL (dllexport) DMC DLL MinGW DLL BCC DLL
__stdcall _Function@n Function _Function@n _Function@n Function@n Function
__cdecl _Function Function Function Function Function _Function

* For all but BCC, which has the same namingconvention for symbols in code and exported name in DLL.

What a mess (especially when you notice that, for MSVC, whether aname is exported by a DEF file or by the__declspec(dllexport) attribute affects itsnaming decoration)! And although the ending decoration clearly shows howmany bytes the called function pops up from stack before returning, it isnot necessarily the most frequently used form. E.g., the Win32 APIfunctions in the system DLLs have no decoration at all, as in the caseones uses a DEF file when exporting functions with MSVC. Many DLLsintended for multi-language usage also follow this practice and use nodecoration with __stdcall functions (although the Java NativeInterface, on Win32 platforms, will accept functions either undecoratedor decorated in the Microsoft way, the latter being the preferredform). The remaining part of this article is thus devoted to thecreation and use of such DLLs with MSVC and MinGW, as well as theintroduction and comparison of related tools (there are good articles athttp://www.bcbdev.com/articles.htmexplaining the complexities of DLLs with Borland C++ Builder, so I neednot bother to say anything more about it).

Tools working with DEF files

First, I will talk about the DEF file format and the relevant tools usedwith MSVC and MinGW. Many intricacies lie here.

DEF file format

We care about only two sections of the DEF file: the LIBRARY section andthe EXPORTS section. The LIBRARY section specifies the internal name ofthe DLL; and the EXPORTS section specifies the function or data items toexport. A short example follows:
LIBRARY    testdll.dll
EXPORTS
    cdeclFunction                       @1
    [email protected]                  @2
    aliasName = cdeclFunction           @3
This DEF file defines three exports for a testdll.dll:the first one is a __cdecl function, the second one a __stdcallfunction, and the third one an alias of the first function (the leftside of the "=" sign is an exported name and the right side the internalname). The three functions are also assigned ordinals. A functioncan be called by its name or its ordinal.

CL

CL can accept a DEF file on the command line, and it simply passesthe file name to LINK. E.g.,
cl /LD testdll.obj testdll.def
will become
link /out:testdll.dll /dll /implib:testdll.lib /def:testdll.def testdll.obj

LINK

LINK is our most important tool when treating DLL and DEF fileswith MSVC. The command line mentioned in CL already shows the optionscommonly used when creating a DLL with a DEF file. The main point is: ifwe do not use a DEF file when creating a DLL, the exported name of a __stdcallfunction will be _Function@n; but if we use a DEFfile, the exported name could be either Function or _Function@n;if both names appear, only the undecorated form is used. However, wecan force both forms of exports with the following lines in the EXPORTSsection:
TestFunction = [email protected]
[email protected] = [email protected]

LIB

If we have the DLL from somebody else (no source available), and we havethe DEF file, the easiest way to create an import library is to use theLIBtool. The following syntax is often enough (check MSDNfor more details):
lib /def:DEF_file
Nota bene: 1) it seems LIB does not accept aliased forms(it will simply ignore the part after the equal-sign); 2) it assumes allfunctions in the DEF file __cdecl. The second point lies in thefact that the import library it produces will map each symbol in the DLLto an internal name with an underscore prefixed, i.e., the linker usingthe import library will try to resolve an undefined symbol _Functionto the symbol Function in the DLL. It takes no special care ofthe __stdcall calling convention. With some techniques we coulduse LIB to produce import libraries for __stdcall functions,but the caller could only call them by ordinal, not by name. The detailsare left as an exercise :-).

gcc

Here we use gcc to call ld. The reason why we do not uselddirectly is that using gcc is generally more convenient. The -sharedoption is specially designed to produce DLLs. We could also use the -Wloption to pass special link options.

ld

GNU ld has many options regarding DLLs, but we shall only focuson four (help information follows):
--add-stdcall-alias                Export symbols with and without @nn
--kill-at                          Remove @nn from exported symbols
--out-implib <file>                Generate import library
--output-def <file>                Generate a .DEF file for the built DLL
Either gcc or ld can accept a DEF file directly on the commandline. When a function (say, [email protected]) is marked as__declspec(dllexport), and we have the following line in theEXPORTS section,
TestFunction = [email protected]
both symbols will be exported to the DLL (LINK has similarbehaviour too). This behaviour is different from dllwrap, whichwe shall talk of immediately.

dllwrap

GNU dllwrap could produce a DLL by a DEF file. We generally usedllwrapin the following syntax,
dllwrap --def DEF_file -o DLL_file OBJ_files [--output-lib LIB_file]
and dllwrap will transparently call gcc, ld, and dlltoolto fulfil its task. If dllwrap is asked to produce an import library(--output-lib), it will let dlltool do it.Unlike LINK or ld, dllwrap will ignore theexport specifications in an object file, and will not export aname unless it is specifically listed as an exported name in the EXPORTSsection (unless one does not use a DEF file at all).

dlltool

GNU dlltool may be used to create the files needed to build anduse dynamic link libraries (DLLs). The following options are of interestto us currently:
-l --output-lib <outname> Generate an interface library.
-D --dllname <name>       Name of input dll to put into interface lib.
-d --input-def <deffile>  Name of .def file to be read in.
-U --add-underscore       Add underscores to symbols in interface library.
-k --kill-at              Kill @<n> from exported names.
dlltool works like LIB, and similarly it willignore the part after the equal-sign in a DEF file, but ithas its special features that somehow compensate for this shortcoming:
  • the -U optionmakes the items in the DEF file map to symbols prefixed with anunderscore in the DLL, and
  • the -k option makes theitems in the DEF file map to symbols stripped of @n inthe DLL.

pexports

This is a stand-alone open-source tool to produce a DEF file from a givenDLL. It is not distributed with MSVC or MinGW, and you may choose to downloadhereif you do not find it elsewhere.

The __stdcall DLL and the import library

Having learnt so much about the tools, now we are ready to do what we wanted.We still need sed (search on the Internet if you do not alreadyhave this useful tool), and a knowledge of regular expression is requiredto understand thoroughly how it works.

Microsoft Visual C++

The simplest way to produce a DLL is to use the /LD command-lineoption of CL:
cl /LD OBJ_files
The resulting DLL will have exported names like [email protected],as is shown in the `MSVC DLL (dllexport)' columnabove. To create symbols with no decoration, we must use a DEF file. Thefollowing is an automatic way to create a DEF file from the DLL if__declspec(dllexport) is used to indicate which functions toexport:
link /out:DLL_file /dll OBJ_files
pexports DLL_file | sed "s/^_\([[:alnum:]_]\+\)@[[:digit:]]\+/\1/" > DEF_file
At this step, you may also want to generate a DEF file to make the DLLusable with MinGW source.
pexports DLL_file | sed "s/^_\([[:alnum:]_]\+\)\(@[[:digit:]]\+\)/\1\2/" > DEF_for_gcc
Once you have the object files and the DEF file, creating the DLL and theimport library can be done in one step:
link /out:DLL_file /dll /def:DEF_file /implib:LIB_file OBJ_files
And you are free to use the DLL and the import library now as you wish.

MinGW GCC

If we do not need to control which functions to export except by __declspec(dllexport),we can type:
gcc -shared -o DLL_file OBJ_files -Wl,--output-def,DEF_file
gcc -shared -o DLL_file OBJ_files -Wl,--kill-at
dlltool -d DEF_file --dllname DLL_file --output-lib LIB_file --kill-at
If we want to use a DEF file to control which functions to export, we canstart by (assuming __declspec(dllexport) is used to indicate whichfunctions to export)
gcc -shared -o DLL_file OBJ_files -Wl,--kill-at,--output-def,DEF_file
to produce a DEF file with exports like "Function =Function@n@Ordinal". After editing it to our will, the following commandswill finish the job:
dllwrap --def DEF_file -o DLL_file OBJ_files
sed "s/[[:alnum:]_]\+ *= *//" DEF_file > New_DEF_file
dlltool -d New_DEF_file --dllname DLL_file --output-lib LIB_file --kill-at
And the import library is now at your hand to use.
 

I am not sure whether I have stated clearly, but I have listed all myfindings when I struggled to find out how to use the DLL tools properlyand how to deal with __stdcall functions in DLLs. Hope you findit useful.

ACKNOWLEDGEMENT: The MinGW mailing list provided much usefulinformation; Luke Dunstan provided important suggestions and corrections.


相關推薦

VS編譯動態的時候沒有生成對應lib檔案

}    具體好像他們又有區別,希望知道的朋友能給解釋下,我也不是很清楚了,我當時就這麼用,然後我的問題搞定了,看了一些資料,也沒搞得很明白,具體有一段英文的好像寫的還比較明白了 一起貼下面了。 Stdcall and DLL tools of MSVC and MinGW The __stdcall cal

VS編譯linux項目生成靜態並在另一個項目中靜態鏈接的方法

能夠 決定 遠程 isp 讓我 comm 位置 編寫 none VS2017也推出很久了,在單位的時候寫linux的服務端程序只能用vim,這讓用慣了IDE的我很難受。 加上想自己擼一套linux上的輪子,決定用VS開工遠程編寫調試linux程序。 在windows下編

VS編譯靜態 .lib 其中Release 版本比Debug版本要大好多原因

bug -1 工程 blog 技術分享 其中 logs debug image 如果工程代碼使用了: 把此選項關閉即可減少庫大小不少: VS編譯靜態庫 .lib 其中Release 版本比Debug版本要大好多原因

vs生產dll時,沒有生產對應lib的問題

原因可能有三個: 1)在Settings->Link中的General選項頁中,選中了“Doesn't produce LIB”複選框。 2)整個動態連結庫中沒有匯出的函式或類。 3)所有匯出函式的實現均寫在在標頭檔案中。 解決辦法: 在工程上右鍵 -> 新增 ->

Android libs/armeabi下面的動態沒有安裝到app-lib的問題

 換到另一個盒子上發現app-lib下面少了好幾個動態庫,在百度是有人提到動態庫的名字要和PACKAGENAME名字一致(是不是PACKAGENAME記不清了)。於是我jni的配置檔案,在瀏覽的過程中我發現用到的庫中libs下面是armeabi-v7a,我馬上意識到這不

Ubantu 新建用戶後沒有生成對應文件夾

reat efs b- 目錄 gin href 創建文件夾 rec vps 原命令:useradd python 改正後:useradd python -m 後成功在home目錄下創建文件夾 原因: man useradd就可以看到如此介紹:Create the user′

Windows系統下靜態動態生成方法

fine end def imp XP fin windows 靜態 style 靜態庫的生成方法:直接創建靜態庫項目,寫好功能後,編譯生成即可,把頭文件和靜態庫提供給別人即可使用 動態庫的生成方法:創建動態庫項目,在頭文件中寫入: #ifdef DLLEXPORT #de

靜態連結LIB)和動態連結(DLL),DLL的靜態載入和動態載入,兩種LIB檔案

靜態連結庫(LIB)和動態連結庫(DLL),DLL的靜態載入和動態載入,兩種LIB檔案。 一、 靜態連結庫(LIB,也簡稱“靜態庫”)與動態連結庫(DLL,也簡稱“動態庫”)的區別 靜態連結庫與動態連結庫都是共享程式碼的方式,如果採用靜態連結庫,則無論你願不願意,lib 中的指令都全部被直接包含在最

Linux下C程式動態生成和呼叫

Linux下C程式動態庫的生成和呼叫 文章目錄 Linux下C程式動態庫的生成和呼叫 1 動態庫的打包和呼叫 2 靜態庫打包和呼叫 3 常用命令 4 gcc 和 g++ 區別 5 編譯和連結的理解

linux編譯動態之-fPIC

在生成動態庫時,常常習慣性的加上fPIC選項,fPIC有什麼作用和意義,加不加有什麼區別,這裡做下小結: fPIC的全稱是 Position Independent Code, 用於生成位置無關程式碼。什麼是位置無關程式碼,個人理解是程式碼無絕對跳轉,跳轉都為相對跳轉。

Linux編譯動態和gdb除錯命令

Linux編譯動態庫和gdb除錯命令TOC IPC命令: 拷貝到當前目錄: cp …/day01/cleanipc . 清除ipc命令: cleanipc zhidao101 all 檢視網路連線: netstat -an | grep 8001 檢視使用者程序: ps -u

VS製作動態注意事項

匯出函式 當我們需要匯出函式的時候,應該考慮的是以標準呼叫約定(stdcall)的形式提供給使用者。具體的呼叫約定的區別可以參考下文。 https://blog.csdn.net/chenlycly/article/details/51329886 在介面宣告檔案中,我們需要定義

Qt動態生成和使用

編譯成動態庫 開啟工程檔案.pro TEMPLATE = lib TARGET = configwifi SOURCES刪除main.cpp make clean make 生成.so檔案 armv6z-mediatek451_001_vfp-linux-gnueabi-s

windows下使用VS編譯libIconv

libiconv是將一種編碼格式轉換為另一種編碼格式的跨平臺開源庫,http://www.gnu.org/software/libiconv/可以檢視支援轉換的編碼型別。但是libiconv 的開發者並沒有釋出windows下的原始碼和庫,要想在windows下使用lib

linux編譯動態之fPIC

今天在用g++編譯程式碼時,提示說.rdata錯誤,然後網上找了一堆資料,最後明白了一個要重新編譯對應的連結庫。 在生成動態庫時,常常習慣性的加上fPIC選項,fPIC有什麼作用和意義,加不加有什麼區別,這裡做下小結: fPIC的全稱是 Position Indepe

Makefile 編譯動態檔案及連結動態

原文轉自 :http://www.cnblogs.com/ljtknowns/p/5647793.html 檔案目錄結構如下 1 dynamiclibapp.c 2 Makefile 3 comm/inc/apue.h 4 comm/errorhandle.c 5

解決linux(ubuntu12.04) ffmpeg編譯後ffplay沒有生成的問題

從官網下載最新版SDL2-2.0.5.tar.gz的原始碼,解壓後cd進目錄,依次執行: ./autogen ./configure make sudu make install 一切順利的話SDL2.0就安裝編譯好了。 庫檔案在 /usr/local/lib

VS動態dll的顯式呼叫(動態呼叫)

VS下動態庫dll的顯式呼叫 動態庫的載入分兩種形式:分為靜態載入和動態載入。靜態載入時,對應的標頭檔案、DLL,和LIB缺一不可,並且生產的EXE沒有找到DLL檔案就會導致“應用程式初始化失敗”。動態載入只需要dll,通過LoadLibrary()函式進行載入,但該方式對

gcc 編譯動態及連結

1.testa.c #include <stdio.h>void Test_a()  {    printf("This is Test_a!");  }   2. testb.c #include <stdio.h>void Test_b(

編譯動態和靜態的Makefile模板

# 1、準備工作,編譯方式、目標檔名、依賴庫路徑的定義。 CC = gcc CFLAGS := -w -g -Wall LIB = libltkc.so HDRS = \ versi