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

QQ登录

只需一步,快速开始

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

刚刚的发现-extern误用

[复制链接]

307

主题

228

回帖

7343

积分

用户组: 真·技术宅

UID
2
精华
76
威望
291 点
宅币
5593 个
贡献
253 次
宅之契约
0 份
在线时间
948 小时
注册时间
2014-1-25
发表于 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

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

使用道具 举报

85

主题

175

回帖

3990

积分

用户组: 超级版主

No. 418

UID
418
精华
14
威望
53 点
宅币
1974 个
贡献
1582 次
宅之契约
0 份
在线时间
252 小时
注册时间
2014-8-9
发表于 2015-9-27 19:43:58 | 显示全部楼层
赞一个!
In the beginning I was not the best.
And the world was also not the best.
But I still know that I am who I am.
Because I think that it is good.
I have been working hard.
I have been keeping growth with the world.
And it was so.
回复

使用道具 举报

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

GMT+8, 2024-4-25 15:05 , Processed in 0.038945 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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