MinGW gcc 编译、调用dll

原创 2015年07月09日 18:01:45

MinGW是Minimalist GNU for Windows, 是在windows平台上做开发的gcc工具集合,支持几乎所有的windows API,几乎可以说是VC的替代,

不过因为GCC原本并不是为windows平台开发的,其主要的目标文件,环境主要是适应Unix和Linux等操作系统,很多在linux下很容易解决的问题,

在windows下却很麻烦。

今天一下午时间都在摆弄MinGW gcc,自己写了一个dll文件并用另一个源文件调用dll中的函数。

一般在VC下很可能使用def文件,但最后很无语的是MinGW连接dll居然什么都没有用,或者是MinGW特性吧。此文把这些过程都记录下来。


环境:

操作系统: Windows 7 sp1 (64 bits),

编译器:MinGW version 4.8.1 (tdm64-2)

先做一个dll,随便编写两个函数即可,当然VC下也可以写一个DllMain ()函数的实现,此处我没有写,只使用了一个关键字__declspec (),一个mydll.h 文件和一个

mydll.c文件:

/*
  author : ez
  date : 2015/7/9
*/

#ifndef _MY_DLL_H
#	define _MY_DLL_H_

#ifdef __cplusplus
extern "C" {
#endif

extern __declspec (dllexport) int add_range (int, int);
extern __declspec (dllexport) double average (int*, int);

#ifdef __cplusplus
}
#endif


#endif // ~_MY_DLL_H_
实现文件mydll.c :

#include "mydll.h"

// __declspec (dllexport) 
int add_range (int _sta, int _end) {
	
	int res = 0;
	if (_sta > _end)
		return 0x7fffffff;
	for (; _sta != _end; _sta ++) {
		res += _sta;
	}
	return res;
	
}

// __declspec (dllexport)
double average (int* _arr, int _cnt) {
	double res = 0.0;
	int i = 0;
	if (_cnt <= 0)
		return (double) (~0);
	for (; i < _cnt; i ++)
		res += _arr [i];
	return (double) (res /= _cnt);
}
之后用gcc编译:

先编译成目标文件:

mingw32-gcc -m32 -c mydll.c

再连接成dll:
mingw32-gcc -m32 -shared - mydll.dll mydll.o

此时即可以得到一个dll文件了,我们可以用HexViewer查看一下是否是合法PE格式文件。

现在来调用这个dll中的函数,我并不想使用它的静态库进行静态编译,只想保留动态链接库,直接由Windows加载器完成所有的调用工作,为此加载器必须知道引用

的dll相关信息,但并不需要在编译期就知道地址都在dll文件的什么偏移量上,可以在运行时动态确定,若不清楚此部分可以查看与PE调用有关的博文。在linux下,如果

使用动态库(linux下一般称为共享库,以so做扩展名的二进制文件,且格式与Windows 的PE完全不同),则直接指定库名称即可,类似以下的命令:

gcc -lpcap -o test  test.c

使用一个 -l 选项即可调用后面指定的库(此例中为libpcap.so,指定库时去掉前面的lib和后面的.so得到库名)。但在windows下这样却行不通,就算把生成的dll前面加上

lib字样,后缀名改为so,也不能用-l 选项指定。后来网上找到很多说要创建一个def文件,VC定义dll时常用的一种文件,文件中列举出了dll导出的所有符号,这样连接器就

可以根据这些信息对dll进行连接,可我却没有找到将def文件输入到GCC的方法,没有类似的选项。而且看到很多博文说将def文件和dll文件通过工具生成a文件,很像windows

下的lib文件,是很多目标文件压缩在一起产生的一种文件。

最终找到的方法确实让我很惊讶,居然简简单单什么都不用做,直接作为输入即可!

以下是调用dll的程序源文件:

/*
  author : ez
  date : 2015/7/9
*/

#include <stdio.h>
#include "mydll.h"

int main (int argc, char* argv []) {
	
	int res = add_range (10, 200);
	printf ("%d\n", res);
	return 0;
}
文件很简单,只调用了add_range (),编译如下:

mingw32-gcc -m32  -o test   test.c  mydll.dll

这样即可!确实很让我无语,“踏破铁鞋无觅处,得来全不费工夫”。


下面把我找到的一些信息也记录一下:

gcc 选项 -Wl:用于给链接器传递参数,

                -soname:指定动态库的soname (Short for object name)

                -output-def = <...> 产生与导出符号相关的def文件

                -out-implib = <*.a> 产生用于提供__img_符号的 .a导入库,即*.a文件


def文件可以使用MinGW 附带的工具pexports生成,输入为dll文件,也可以使用VC附带的工具dumpbin 生成。

MinGW 附带的dlltool 工具可以讲def 文件转化成 *.a文件。

版权声明:本文为博主原创文章,未经博主允许不得转载。

MinGW gcc 生成动态链接库 dll 的一些问题汇总

网络上关于用 MinGW gcc 生成动态链接库的文章很多。介绍的方法也都略有不同。这次我在一个项目上刚好需要用到,所以就花了点时间将网上介绍的各种方法都实验了一遍。另外,还根据自己的理解试验了些网上...

MSVC vs. MinGW 之dll玩转攻略手记

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...
  • byxdaz
  • byxdaz
  • 2014年08月16日 19:17
  • 5495

VC 调用 MinGW 生成的dll

首先,如何dll 中导出了C++的类,那么就不要折腾了。不同的编译器编译出来的C++代码是不保证通用的。如果dll中只是一些C 函数,那么是可以互相调用的。   MinGW 生成dll时即使生成了 ....

MinGW编译的EXE需要DLL的问题

MinGW编译的EXE需要DLL的问题 MinGW升级到4.5.2生成的exe需要libgcc_s_dw2-1.dll和libstdc++-6.dll  -static-libgc...

MinGW 与 MSVC 生成 DLL 各种情况的折腾笔记

写这篇博客,主要是刚折腾 MinGW,相关内容网上的资料不全,而且错误很多 其实之前我根本没把这个当回事,我就想 MinGW 跟 Linux 上的 GNU 编译器不会有差别,但是事实却不是这样。。。...

MinGW与MSVS生成dll库的交叉链接

MinGW生成的.dll文件可以直接用MinGW链接,就像链接一般静态库一样。但是若希望在MSVC中使用,则要么需要生成.lib信息头文件,要么在源码中调用windows API的GetProcAdd...

mingw如何使用VC编译的dll

什么也不说了,看例子 采用ming C编译,将ming/bin加入path (注:pythonxx.dll一般在winnt/system32下,以下操作后文件如xx.def,xx.a放到pytho...

Windows使用GCC调用DLL内部的类

 IDE:DEV-C++GCC 4.1.2需要以下步骤:1.将DLL工程的 XX.a,XX.def,XX.dll 以及类的头文件拷贝到工程文件夹2.工程包含类的头文件3.在“工程选项”-》“参数”-》...

gcc编译dll和调用dll

方法一: 共有三个文件:print.h,print.c,test.c ***************************************************************pr...

MinGW下载并配置gcc\g++编译环境

本文将讲解如何下载MinGW并配置gcc\g++编译环境
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:MinGW gcc 编译、调用dll
举报原因:
原因补充:

(最多只允许输入30个字)