• extern "C" 使用的原因


    1)使用vc6 编写动态库,动态库源码 (dll_test.cpp) 如下:

    #include <windows.h>
    
    // _declspec(dllexport) means test() can be called by others
    void _declspec(dllexport) test() 
    {
        MessageBox(NULL, "call test() success!", "test", MB_OK);
    }
    
    BOOL APIENTRY DllMain(HANDLE a, DWORD b, LPVOID c)
    {
        MessageBox(NULL, "in DllMain", "main", MB_OKCANCEL);
    
        return TRUE;
    }

    生成动态库为 dll_test.dll,把它放到添加到系统可以找到的目录

    在“运行中调用”

    rundll32 dll_test.dll,test

    有如下错误提示

    使用 depends 分析原因

    发现在 导出的函数名前后都有乱码,将其复制后,再次执行

    rundll32 dll_test.dll,?test@@YAXXZ

    2)修改源码,如下:

    #include <windows.h>
    
    // _declspec(dllexport) means test() can be called by others
    extern "C" void _declspec(dllexport) test() 
    {
        MessageBox(NULL, "call test() success!", "test", MB_OK);
    }
    
    BOOL APIENTRY DllMain(HANDLE a, DWORD b, LPVOID c)
    {
        MessageBox(NULL, "in DllMain", "main", MB_OKCANCEL);
    
        return TRUE;
    }

    编译生成动态库后,通过 depends 查看:

    同时使用 rundll32 dll_test.dll,test 进行测试,有正确结果如下:

    3)原因分析

    extern "C" 是告诉编译器用C语言的方式给函数命名。在用VC制作DLL导出函数时,由于C++存在函数重载,为了

    实现同样的函数名可因参数不同而存在,所以在VC处理这些函数时,会把函数名编译成不同的名字以便自己识别。

    例如:

    int test(int, int) -> test@@YAHHH@Z

    float test(float, float) -> test@@YAMMM@Z

    但当我们使用 extern "C" 时,编译器会标识为: _函数名

    int test(int, int) -> _test

    float test(float, float) -> _test

    因此被 extern "C" 修饰过的函数不再具备重载能力。

  • 相关阅读:
    深入理解jsonp跨域请求原理
    vue项目性能优化总结
    脱离Office约束,C#结合Mpxj组件完美解析MSProject(.mpp)文件
    将list转换成DataTable
    json时间格式化
    C# DES加密解密
    asp.net mvc ViewBag常用操作
    Jquery ajax与asp.net MVC前后端各种交互
    存储过程实现树形目录外联其他表实现每个节点的统计
    CSS自定义右键菜单
  • 原文地址:https://www.cnblogs.com/aqing1987/p/4596893.html
Copyright © 2020-2023  润新知