刚刚的发现-extern误用
一直以来都误用了,来看这种情况:假设要从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
在此抛砖引玉了,如果大家有更多发现请指出 赞一个!
页:
[1]