• extern "C" 和 DEF 文件.


    参考:

    http://www.cnblogs.com/whiteyun/archive/2011/07/22/2113560.html

    问题: 如果用了 DEF 文件来导出 DLL 的函数, 还需要在导出的函数声明前面加 extern "C" 吗?

    DEMO 下载: http://pan.baidu.com/s/1kTTY6rH

    extern "C" 的目的是告诉 C++ 编译器不要对函数名进行改名处理(以便支持函数重载), 而是按照 C 编译器的方式, 不对函数名进行修改.

    如果专门有头文件声明函数的话, extern "C" 以及 __declspec(dllexport) 只需要出现在头文件中即可, 定义函数的 .cpp 文件中可有可无.

    如果没专门有头文件声明函数的话, extern "C" 以及 __declspec(dllexport) 必须出现在定义函数的 .cpp 文件中.

    上述规则对纯 C 项目中的 __declspec(dllexport) 也适用.

    做的实验, 思路如下, 即看各种配置下 Hello.h 中需不需要加 extern "C" 从而 UI2.EXE 可以通过 GetProcAddress("fnHello") 找到 Hello.dll 中的 fnHello:

    注: Hello 项目中有一个 Hello.h

     1 UI2.EXE 编译为 C++ 项目 , HELLO.DLL 编译为 C++ 项目, C++ 编译器版本相同, Hello.h 中, 用 __declspec(dllexport) :
     2     Hello.h 有 extern "C", 成功, dumpbin /exports hello.dll 得到 _fnHello
     3     Hello.h 无 extern "C", 失败, dumpbin /exports hello.dll 得到 ?fnHello@@YAXXZ
     4 UI2.EXE 编译为 C++ 项目 , HELLO.DLL 编译为 C++ 项目, C++ 编译器版本相同, Hello.h 中, 无 __declspec(dllexport), 用 DEF 文件:
     5     Hello.h 有 extern "C", 成功, dumpbin /exports hello.dll 得到 _fnHello
     6     Hello.h 无 extern "C", 成功, dumpbin /exports hello.dll 得到 ?fnHello@@YAXXZ
     7 UI2.EXE 编译为 C++ 项目 , HELLO.DLL 编译为 C 项目, Hello.h 中, 用 __declspec(dllexport):
     8     Hello.h 有 extern "C", 成功, dumpbin /exports hello.dll 得到 _fnHello
     9     Hello.h 无 extern "C", 成功, dumpbin /exports hello.dll 得到 _fnHello
    10 UI2.EXE 编译为 C++ 项目 , HELLO.DLL 编译为 C 项目, Hello.h 中, 无 __declspec(dllexport), 用 DEF 文件:
    11     Hello.h 有 extern "C", 成功, dumpbin /exports hello.dll 得到 _fnHello
    12     Hello.h 无 extern "C", 成功, dumpbin /exports hello.dll 得到 _fnHello
    13 UI2.EXE 编译为 C 项目 , HELLO.DLL 编译为 C++ 项目, Hello.h 中, 用 __declspec(dllexport):
    14     Hello.h 有 extern "C", 成功, dumpbin /exports hello.dll 得到 _fnHello
    15     Hello.h 无 extern "C", 失败, dumpbin /exports hello.dll 得到 ?fnHello@@YAXXZ
    16 UI2.EXE 编译为 C 项目 , HELLO.DLL 编译为 C++ 项目, Hello.h 中, 无 __declspec(dllexport), 用 DEF 文件:
    17     Hello.h 有 extern "C", 成功, dumpbin /exports hello.dll 得到 _fnHello
    18     Hello.h 无 extern "C", 成功, dumpbin /exports hello.dll 得到 ?fnHello@@YAXXZ

    总结:
    当 DLL 是 C++ 实现的时候,
    用 DEF 文件, 无 extern "C", 此时 DLL 中导出的函数名仍然会被 C++ 编译器修改, 但仍然可用 GetProcAddress 找到函数.
    用 __declspec(dllexport), 如果没有 extern "C", GetProcAddress 找不到函数.

    当 DLL 是 C 实现的时候,
    因为用的 C 编译器, 所以无论用 DEF 文件还是 __declspec(dllexport), 都不需要 extern "C", DLL 中导出的函数名始终不会被修改.
    GetProcAddress 始终能找到函数.

  • 相关阅读:
    freemarker报错之十一
    freemarker定义一个连续的序列
    freemarker报错之十
    freemarker之数组
    解决linux环境下nohup: redirecting stderr to stdout问题
    如何查看Linux操作系统版本?
    log file sync
    freemarker中的round、floor和ceiling数字的舍入处理
    freemarker中的split字符串分割
    freemarker中的left_pad和right_pad
  • 原文地址:https://www.cnblogs.com/qrlozte/p/5101573.html
Copyright © 2020-2023  润新知