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 ...
随机推荐
- ELK菜鸟手记 (四) - 利用filebeat和不同端口把不同服务器上的log4j日志传输到同一台ELK服务器
1. 问题描述 我们需要将不同服务器(如Web Server)上的log4j日志传输到同一台ELK服务器,介于公司服务器资源紧张(^_^) 2. 我们需要用到filebeat 什么是filebeat ...
- 3分钟带你了解PowerShell发展历程——PowerShell各版本资料整理
本文带你了解PowerShell发展历程,顺便整理了一点资料,方便大家查询. Windows PowerShell® 是基于任务的命令行管理程序和脚本语言,专为进行系统管理而设计. 在 .NET Fr ...
- Html5语义化标签详解及其兼容性处理
<header></header> 页眉 主要用于页面的头部的信息介绍,也可用于板块头部 <hgroup></hgroup> 页面上的一个标题组合 一个 ...
- JVM-7.Java内存模型与高效并发
更多内容参见<并发与同步>系列 一.引子 二.JMM 三.Java中的线程 四.线程安全 五.锁优化 一.引子 运算能力 摩尔定律:晶体管数量,代表的CPU的频率 Amdahl ...
- Coursera 机器学习笔记(二)
主要为第三周课程内容:逻辑回归与正则化 逻辑回归(Logistic Regression) 一.逻辑回归模型引入 分类问题是指尝试预测的是结果是否属于某一个类. 维基百科的定义为:根据已知训练区提供的 ...
- 有关typename
为了避免潜在的语法解析二义性,你需要在从属于形式类型参数的类型名前面使用typename,这样的类型被称为从属类型(dependent type) (摘自effective STL)
- openjdk8之编译和debug
系统环境为ubuntu 16.04,uname -a: Linux ddy-Aspire-V5-573G 4.4.0-21-generic #37-Ubuntu SMP Mon Apr 18 18:3 ...
- IntelliJ IDEA的激活和汉化
1.下载 IntelliJ IDEA 下载地址 Community 社区版,免费使用,下载后发现没有JAVA EE,推荐下载 Ultimate Ultimate 需要注册码. 2.激活 我下载的是20 ...
- Ajax 跨域提交表单
跨域提交表单,前端ajax不用做任何修改, 只需要在后端调用的方法里面添加一行代码即可. .NET 版 HttpContext.Response.AddHeader("Access-Cont ...
- Ruby中文乱码问题
中文乱码问题 解决方法为只要在文件开头加入 # -*- coding: UTF-8 -*-(EMAC写法) 或者 #coding=utf-8 就行了. 源代码文件中,若包含中文编码,则需要注意两点: ...