zoukankan      html  css  js  c++  java
  • 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" 修饰过的函数不再具备重载能力。

  • 相关阅读:
    spring中各个模块的作用
    《Spring实战》学习笔记-第四章:面向切面的Spring
    《Spring实战》学习笔记-第四章:面向切面的Spring
    Centos7下永久修改mysql5.6最大连接数
    Prefix-List
    Route-Map
    PBR Lab2
    Lab PBR
    ISIS超载位解决流量黑洞
    ISIS TLV
  • 原文地址:https://www.cnblogs.com/aqing1987/p/4596893.html
Copyright © 2011-2022 走看看