找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 2377|回复: 1

刚刚的发现-extern误用

[复制链接]
发表于 2015-9-25 13:58:34 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
一直以来都误用了,来看这种情况:

假设要从ntoskrnl.lib导入IoDriverObjectType
extern "C"
{
  POBJECT_TYPE *IoDriverObjectType;
};

这样写可以嘛?
原先以为extern "C"这个extern已经代表了extern本身,然而发现并不是。

如果查看导入表,会发现没有符号,也就是编译器当成全局变量处理
这个例子其实很特殊,如果该符号是个函数的话,那么编译器自然按有无extern分 _imp_和非_imp_处理导入表
然而此时是个变量,外层extern "C"只做符号修饰说明,并不能代表extern 本身!

(引入函数可以用 有extern,和无extern,前者生成_imp_符号的导入表)

也就是说上述语句相当于c文件:
POBJECT_TYPE *IoDriverObjectType;

如果这是个函数,则可以正常引入,而作为变量,编译器会当做本文件声明的变量
所以正确引入方式为:
extern "C"
{
  extern POBJECT_TYPE *IoDriverObjectType;
};

分析了有无extern的区别,再来看有无__declspec(dllimport)的区别:
extern "C"
{
  __declspec(dllimport) POBJECT_TYPE *IoDriverObjectType;
};
可以发现在引用到改变量处 使用的是*(DWORD*)__imp__IoDriverObjectType
而使用extern的是__imp__IoDriverObjectType

在此抛砖引玉了,如果大家有更多发现请指出
回复

使用道具 举报

发表于 2015-9-27 19:43:58 | 显示全部楼层
赞一个!
回复

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-11-25 12:11 , Processed in 0.030298 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表