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,发现函数变成了"foo@4"。
网上的说法是使用__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()
- 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
MinGW(GCC)编译DLL文件的更多相关文章
- windows MinGW gcc 编译乱码问题
问题描述 一般很多编辑器默认都是保存成utf-8文件,然而在输出中文的时候出现了乱码?另外试了其他方法,有的乱码,有的不乱? MinGW gcc 编译 utf-8 文件的时候乱码 MinGW gcc ...
- windows下用GCC编译DLL
此程序有3个文件,分别为 export.h .export.c .main.c export.h 文件内容 /*此头很有必要,别人在调用的时候知道有哪些方法*/ #ifdef BUILD_DLL #d ...
- 在Linux下使用gcc编译mesa文件报undefined reference to symbol 'sin@@GLIBC_2.2.5和DSO missing from command line两个错误的解决方案
一.概述 在Linux系统下使用gcc编译用C语言写的mesa的示例程序. 环境:Ubuntu Server 18.04.1 二.问题的出现 在Ubuntu下安装好mesa所需的库文件,将目标文件从g ...
- Ubuntu下使用gcc编译c文件,未识别cos,sin
Ubuntu下使用gcc编译c文件,虽然我调用了math.h的头文件,但是未识别cos,sin 报错:( fft.c ) /tmp/ccwXjD8C.o: In function `fft': fft ...
- 反编译DLL文件
我们平时在工作中经常会遇到一些已经被编译后的DLL,而且更加麻烦是没有源代码可以进行修改,只能针对这个DLL的文件进行修改才能得到我们想要的结果:本文将通过一个实例来演示如果完成一个简单的修改;我们将 ...
- 用Reflector for .NET反编译dll文件(.net),把整个dll导出个cs插件
Reflector for .NET 下载地址: http://www.aisto.com/roeder/dotnet/ Reflector.FileDisassembler.zip下载地址: htt ...
- gcc 编译c++文件
#include <stdio.h> //将类定义在命名空间中 namespace Diy{ class Student{ public: char *name; int age; flo ...
- 如何反编译DLL文件
1.利用反编译器,多种工具,本次选用Reflector 8.5. 2.界面如下:
- dll = MinGW gcc 生成动态链接库 dll 的一些问题汇总
MinGW gcc 生成动态链接库 dll 的一些问题汇总 https://blog.csdn.net/liyuanbhu/article/details/42612365 网络上关于用 MinGW ...
随机推荐
- iOS textfield 限制输入字数长度
iOS textfield限制输入的最大长度 [self.textFiled addTarget:self action:@selector(textFieldDidChange:) forContr ...
- Aspose.Cells.dll操作execl
附件:Aspose.Cells.dll 1.创建execl(不需要服务器或者客户端安装office) public void DCExexl(DataTable dt) { Workbook wb ...
- nginx+tomcat集群负载均衡(实现session复制)
转自:http://talangniao.iteye.com/blog/341512 架构描述 前端一台nginx服务器做负载均衡器,后端放N台tomcat组成集群处理服务,通过nginx转发到后面( ...
- struts2.1.6教程三、在Action获取Scope对象
引言:在前面的Action操作中,关键就是Action中的exectue方法,但是此方法并没有request.session.application等对象作为参数,自然就不能利用这些对象来操作.下面我 ...
- 用css3过滤做遮罩效果
<!DOCTYPE html><html ng-app="myApp" ng-controller="myController">< ...
- Java ClassLoader 原理分析
一.ClassLoader(类加载器)的作用 如果一个程序包含不止一个class文件,那么当程序启动时,带有main方法的类的class文件作为程序入口先被JVM加载,然后根据程序调用的需要,再逐步进 ...
- SpringMVC——数据校验
数据校验在web应用里是非常重要的功能,尤其是在表单输入中.在这里采用Hibernate-Validator进行校验,该方法实现了JSR-303验证框架支持注解风格的验证. 一.导入jar包 若要实现 ...
- jquery attr处理checkbox / select 等表单元素时的坑
先上html结构 <body> <form action=""> <input type="checkbox" id=" ...
- Java File类应用:递归遍历文件夹和递归删除文件
要求: 1)采用递归遍历文件夹下的所有文件,包括子文件夹下的文件 2)采用递归删除文件下的所有文件 注意: 以下递归删除文件的方法,只能删除文件,所有的文件夹都还会存在 若要删除正文文件夹,可以在递归 ...
- Java IO流之打印流与标准流
一.打印流 1.1打印流特点与构造方法 1)PrintStream和PrintWriter类都提供了一系列重载的print和println方法来输出各种类型的数据. 2)PrintStream和Pri ...