Mingw & VC -- DLL

本文详细介绍了如何使用MinGW和VC(Visual C++)生成DLL,并提供了静态调用与动态调用的具体方法。此外,还对比了不同编译环境下DLL的调用约定差异及其解决办法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Mingw 生成dll

gcc test.c -shared -o libtest.dll -Wl,--output-def,libtest.def,--out-implib,libtest.a

同时生成了 a.def liba.a


VC (VC6.0)生成dll

File->New->Win32 Dynamic-Link Library … 添加代码使用__declspec(dllexport)或者使用def文件配置好导出函数或变量编译

会生成 dll lib两个文件

 

Mingw使用Mingw生成的dll

静态调用

gcc test_main.c –o test_main.exe –L. –llibtest

动态调用

gcc test_main.c –o test_main.exe –lkernel32

 

代码中使用

#include <windows.h>

HMODULE hdll = LoadLibrary("libtest.dll");

If(hdll != NULL) {

函数指针= GetProcAddress(hdll, "函数名");

函数指针();

}

动态调用使用GetProcAddress取得函数指针时必须使用生成的def文件中

指明的函数名使用g++编译出的dll由于C++函数重载的原因会改变函数名

 

VC使用VC生成的dll

静态调用

Project->Setting->Link->Project Options 填入libtest.lib

编译

libtest.dll 拷贝至运行目录

运行程序

 

动态调用

不需要libtest.lib代码与mingw动态调用同

注意函数名也需要使用 def文件中指明的函数名

 

Mingw使用VC生成的dll

两种比较常用函数调用约定 __cdecl __stdcall

 

1dll中函数调用约定为__cdecl

mingw可以通过-l直接链接该dll

gcc sample.c –o sample.exe –L.-llib_a.dll

代码中包含dll的头文件然后就可以调用dll中的函数了

 

2dll中的函数调用约定为__stdcall

mingw就不能直接链接了

Windows底层api全部为__stdcall调用约定不能直接调用

mingw已经帮我们生成了一批可以直接调用的库文件

mingw安装目录的lib文件夹下

如果我们想链接kernel32.dll则可以直接使用-lkernel32

gcc会链接lib下的libkernel32.a  通过.a调用真正的kernel32.dll

 

如果只有一个__stdcall调用约定的dll文件

则需要通过以下步骤自己生成.a文件

pexports xxx.dll > xxx.def

dlltool --dllname xxx.dll --def xxx.def --output-lib libxxx.dll.a

pexports需要到网上自行下载 dlltoolmingw自带的工具)

生成.a文件后就可以使用-l链接在运行程序时需要将dll放在运行目录下

 

一般情况下使用VC生成的dll文件都是__cdecl调用约定

除非定义函数时显示指定__stdcall调用约定

因此一般情况下 VC生成的dll mingw可以直接通过-l选项链接

 

VC使用Mingw生成的dll

VC无法使用Mingwa文件也不能像mingw那样直接调用dll文件

如果调用mingw生成的dll则需要通过以下步骤得到相应的lib文件通过lib文件调用

 

pexports xxx.dll > xxx.def (pexports mydll.dll -o > mydll.def)

lib /machine:ix86 /def:xxx.def  (也有执行 lib /machine:i386 /def:avcodec-54.def /out:avcodec.lib)

(libVC自带的工具)

 

生成lib文件后剩下的就和VC调用VC产生的dll类似了

 

(目前测试 Mingw产生dll .h文件中的函数需使用 extern "c" 声明导出函数可以使用导出变量还不可以不知道哪里还需要下点功夫)

http://blog.sina.com.cn/s/blog_5ea0192f010102ig.html

MSVC vs. MinGW 之 (lib,dll,def,obj,exe) vs (a,dll,def,o,exe) 玩转攻略手记 一份粗糙的研究记录,有待补完和整理。 MinGW: c -&gt; o gcc -c a.c c -&gt; exe gcc a.c libs.o -o a.exe (从主程序a.c,附加libs,生成a.exe) o -&gt; exe gcc a.o b.o ... -o main.exe c -&gt; dll,def,a gcc a.c -shared -o a.dll -Wl,--output-def,a.def,--out-implib,liba.a a -&gt; dll a2dll liba.a dll -&gt; a: dlltool --dllname a.dll --def a.def --output-lib liba.a (需要def文件) a -&gt; def: dumpbin /exports lib.a &gt; lib.def (在windows上调用def需要修改) dll -&gt; def : pexports a.dll -o &gt; a.def (这里的-o是指给函数标序号) lib -&gt; def : reimp -d a.lib lib -&gt; a: (for __cdecl functions in most case) reimp a.lib; (for __stdcall functions) MSVC: c -&gt; lib cl /LD a.c (注意已经定义了export列表) c -&gt; dll cl /LD a.c c -&gt; obj cl /c a.c c -&gt; exe cl a.c /out:a.exe dll -&gt;lib lib /machine:ix86 /def:a.def /out:a.lib (需要def文件) obj -&gt;lib lib a.obj b.obj... /out:mylib.lib dll -&gt;def DUMPBIN a.dll /EXPORTS /OUT:a.def (生成的def需要做修正) lib -&gt;def reimp -d a.lib (这个要在MSYS+MinGW下用) 关于这些工具的适用范围可以很容易的理解和记忆。 dll和exe都是PE文件,所以可以使用pexports. lib和a是静态库文件,都是归档类型,不是PE格式。所以不能使用pexports. dll可以使用dlltool. lib可以使用lib, 和reimp(lib-&gt;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 &quot;mylib.h&quot; using namespace std; int main() { char str[]=&quot;Hello world!&quot;; printhello(str); return 0; } 2. mylib.cpp #include #include #include &quot;mylib.h&quot; using namespace std; void EXPORT printhello(char *str) { cout &lt;&lt; str &lt;&lt; endl; } 3. mylib.h #define EXPORT __declspec(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值