• 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 FilesCodeBlocksMinGW"
    PATH=%MINGW_HOME%in;%PATH%

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

    d:	est>
    #执行编译命令
    d:	est>mingw32-gcc -c -DBUILD_DLL mydll.c
    #执行链接命令,生成mydll.dll和静态库文件libmydll.a
    d:	est>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:	estmydll.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

  • 相关阅读:
    在opencv3中实现机器学习之:利用正态贝叶斯分类
    在opencv3中进行图片人脸检测
    在opencv3中利用SVM进行图像目标检测和分类
    在opencv3中实现机器学习之:利用svm(支持向量机)分类
    在matlab和opencv中分别实现稀疏表示
    opencv2学习:计算协方差矩阵
    用python简单处理图片(3):添加水印
    Google protocol buffer在windows下的编译
    GEOS库学习之五:与GDAL/OGR结合使用
    GEOS库学习之四:几何关系判断
  • 原文地址:https://www.cnblogs.com/lichmama/p/4126323.html
Copyright © 2020-2023  润新知