MinGW(GCC)编译DLL文件

这两天用CB(Code::Blocks)写个小程序,要编译出DLL供VB(6)使用。CB使用mingw-gcc作为编译器,在库文件的产出上跟VC、VS之类的IDE略有不同。

由于C语言的基础知识不是太好,尤其对编译环节更是知之甚少。结果,试了几次,导出的DLL中的函数总是无法被调用。

用VB加载时总是提示"DLL调用约定错误",百度之了解到VB只能调用适配__stdcall约定(这也是其他语言也能调用C的默认方式)的函数。

于是在源文件中的函数前加上__stdcall,导出后又提示"找不到DLL入口点foo in mydll.dll",搜索得知可能是导出函数的名字有问题。

打开DLL Export Viewer,载入mydll.dll,发现函数变成了"[email protected]"。

网上的说法是使用__stdcall的副作用,可以用extern "C"来避免,于是又加上extern "C",结果依旧。

还有人说可以用DEF文件来控制导出的函数名,不过我也没查到具体该怎么加入到编译过程中。

不断google&baidu之后,发现gcc可以在链接阶段通过指定--kill-at参数来消除这种情况。于是,紧接着又了解了下gcc的使用方法,尝试几次后终于成功了。

在这不得不吐槽部分人写的技术博客,很多问题就是只言片语带过,让人看得云里雾里。我觉得人可以说错话,但是起码要把自己的意思表达清楚,不然胡乱凑出一篇误人误己。

这里编写个简单例子来说明下具体是如何操作的:

建立DLL项目,结构如下:

test/
----mydll.h
----mydll.c

头文件:mydll.h

#ifndef __MYDLL_H__
#define __MYDLL_H__

#ifdef BUILD_DLL
    #define DLL_EXPORT __declspec(dllexport)
#else
    #define DLL_EXPORT __declspec(dllimport)
#endif

#ifdef __cplusplus
extern "C" {
#endif
    DLL_EXPORT int __stdcall foo(int x);
#ifdef __cplusplus
}
#endif

#endif // __MYDLL_H__

C文件:mydll.c

#include "mydll.h"

DLL_EXPORT int __stdcall foo(int x) {
    return x;
}

如果你安装了Code::Blocks(和MinGW),那么创建环境变量:

MINGW_HOME=C:\Program Files\CodeBlocks\MinGW
PATH=%MINGW_HOME%\bin;%PATH%

打开命令行,进入我们的项目路径中:

d:\test>
#执行编译命令
d:\test>mingw32-gcc -c -DBUILD_DLL mydll.c
#执行链接命令,生成mydll.dll和静态库文件libmydll.a
d:\test>mingw32-gcc -shared -o mydll.dll mydll.o -Wl,--kill-at,--out-implib,libmydll.a
Creating library file: libmydll.a

以上,就是我们生成DLL的全过程了。

接下来,打开VB我们来验证下:

Private Declare Function foo Lib "d:\test\mydll.dll" (ByVal x As Integer) As Integer

Private Sub Form_Load()
    Debug.Print foo(10)
End Sub

运行OK,立即窗口输出10。

用Python测试下:

>>> import ctypes
>>> mydll = ctypes.windll.LoadLibrary("d:\\test\\mydll.dll")
>>> print mydll.foo(10)
10
>>> 

好,也没问题,那么证明结果上是正确的。

当然,由于本人水平较低,文章中肯定有描述不正确的地方,各位大神如果如果看到还请不吝指教。

参考文档:

http://baike.baidu.com/view/2814224.htm

http://baike.baidu.com/view/1276580.htm?fr=aladdin

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

时间: 2024-11-05 15:53:25

MinGW(GCC)编译DLL文件的相关文章

windows下用GCC编译DLL

此程序有3个文件,分别为 export.h .export.c .main.c export.h 文件内容 /*此头很有必要,别人在调用的时候知道有哪些方法*/ #ifdef BUILD_DLL #define EXPORT __declspec(dllexport) #else #define EXPORT __declspec(dllimport) #endif EXPORT void export(void); export.c 文件内容 #include<stdio.h> #inclu

关于在linux下用gcc编译头文件的问题。

关于在linux下用gcc编译头文件的问题. 2011-01-21 18:5215052135380 | 分类:其他编程语言 | 浏览8139次 有node.h prepare.h list.h file.h 这四个头文件, prepare.h中用到了node.h, list.h中用到了preapre.h , file.h中用到了list.h ,怎么用gcc对这四个头文件进行编译. 分享到: 2011-01-22 02:23 天天爱答题,抽奖送惊喜~ 提问者采纳 我用一个例子来告诉你怎么样在 C

在Linux下使用gcc编译mesa文件报undefined reference to symbol &#39;[email&#160;protected]@GLIBC_2.2.5和DSO missing from command line两个错误的解决方案

一.概述 在Linux系统下使用gcc编译用C语言写的mesa的示例程序. 环境:Ubuntu Server 18.04.1 二.问题的出现 在Ubuntu下安装好mesa所需的库文件,将目标文件从github上克隆下来之后编译. 以上截取的是用gcc编译目标文件和传参的介绍: gcc:源程序将用gcc编译器进行编译: osdemo,c:将要被编译的源程序: -lOSMesa:链接OSMesa库: -lGLU:链接GLU库: -lGL:链接GL库: -o:指定目标名称: osdemo:编译后生成

用Reflector for .NET反编译dll文件(.net),把整个dll导出个cs插件

Reflector for .NET 下载地址: http://www.aisto.com/roeder/dotnet/ Reflector.FileDisassembler.zip下载地址: http://www.denisbauer.com/NETTools/FileDisassembler.aspx 1. 下载Reflector.FileDisassembler.zip,解压后得到一些文件,其中Reflector.FileDisassembler.dll是已经编译好的,其它是它源码: 2.

用Gcc编译C文件时出现错误,提示用c99标准

c原文件 #include<stdio.h> #include<stdlib.h> #define MAX(A,B) A>B?A:B        //返回A,B中的最大值 #define LOOP(FROM,TO,CONTENT)         for(int index=FROM;index<TO;index++){                CONTENT         }                 int main(void) {         

如何反编译DLL文件

1.利用反编译器,多种工具,本次选用Reflector 8.5. 2.界面如下:

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

网络上关于用 MinGW gcc 生成动态链接库的文章很多.介绍的方法也都略有不同.这次我在一个项目上刚好需要用到,所以就花了点时间将网上介绍的各种方法都实验了一遍.另外,还根据自己的理解试验了些网上没有提到的方法.这里,我就将这两天获得的成果总结一下. 首先说一下我的开发环境: gcc version 4.9.2 (Rev1, Built by MSYS2 project) Target: i686-w64-mingw32 Thread model: posix --disable-sjlj-

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

MinGW gcc 生成动态链接库 dll 的一些问题汇总 https://blog.csdn.net/liyuanbhu/article/details/42612365 网络上关于用 MinGW gcc 生成动态链接库的文章很多.介绍的方法也都略有不同.这次我在一个项目上刚好需要用到,所以就花了点时间将网上介绍的各种方法都实验了一遍.另外,还根据自己的理解试验了些网上没有提到的方法.这里,我就将这两天获得的成果总结一下. 首先说一下我的开发环境: gcc version 4.9.2 (Rev

用 ilasm 反编译、修改.net dll文件

有些.net dll我们没有源码,如果要修改某些东西,可以用ilasm.exe反编译为il代码,修改后再编译回dll ilasm通常放在以下路径 C:\Windows\Microsoft.NET\Framework\v4.0.30319\ilasm.exe 反编译dll 用ilasm打开一个dll文件,然后点击[文件]->[转储] 点击[确定]保存为一个il文件 用vs打开il文件进行修改,然后用以下命令,重新编译dll文件 如果反编译出来的dll带了res资源文件,编译回去的时候需要加参数/R