• __declspec(dllimport)的小秘密(转)


    昨天和同事使用一个dll(lib+dll)的时候,发现他在引用头文件是,并没有使用__declspec(dllimport),但是程序完全运行正常,不明觉厉下,去网上翻了下资料,原来是链接器的原因,这里贴一个转帖,已经写得很清楚了。

    邓立波 深圳,2008-6

    作者联系方式:

    email:    libodeng@gmail.com

    msn:     libodeng@gmail.com

            按照MSDN说明,当链接dll的导出函数时,只需要包含头文件和lib,__declspec(dllimport)修饰符不是必须的,但加上该修饰能使导出函数的调用效率更高。那么,究竟原因是什么?

    假设dll导出了一个函数:
    extern "C" __declspec(dllexport) void fun();
    如果程序中声明不加__declspec(dllimport),查看调用fun()函数的汇编代码:
        004010AD   call        fun (004010d8)
    其中fun被定义为一个标号(label),如下:
    fun:
        004010D8   jmp         dword ptr [__imp__fun (0040e0e8)]
    上面的符号__imp__fun指向的地址为fun()函数在exe中的导入节。

    当声明加上__declspec(dllimport)后,查看调用fun()函数的汇编代码:
        004010AB   call        dword ptr [__imp__fun (0040e0e8)]

    从上面可以看出,加上__declspec(dllimport),编译器链接dll将省略一条jmp语句。
    这是因为:

    1。如果导出函数的声明没有用__declspec(dllimport) 修饰的话,编译器并不知道这个函数是由DLL导出的,所以编译器就把这个函数当作普通的外部引用来对待,产生一个外部引用的符号等着链接器解析。当链接器工作的时候,它是不能修改编译器生成的结果,所以会将该符号解析为对相应函数调入节的间接调用。

    2。如果导出函数的声明用__declspec(dllimport) 修饰的话,编译器一开始就知道这个函数是DLL导出函数,直接编译成对调入节的调用。

    原文:http://libo.deng.blog.163.com/blog/static/40157422200851124138373/

  • 相关阅读:
    .NET牛人应该知道些什么
    秋梦
    感谢你走进我的生命里
    漂流有感
    QQ在跳舞
    青春无痕
    名人只是传说,你我才是传奇
    祝福紫秋
    可以用在任何人身上:百战百胜人生10大成功秘诀
    c#发送邮件
  • 原文地址:https://www.cnblogs.com/xiaosuiba/p/3843945.html
Copyright © 2020-2023  润新知