免費論壇 繁體 | 簡體
Sclub交友聊天~加入聊天室當版主
分享
返回列表 发帖

驱动代码中C和C++代码区别


  A、函数调用约定
  B、C和C++编译方式
  C、用C++方式编译驱动  
  D、C代码升级至C++
  E、优化21课的代码
课时:16分

*.c
当文件后缀名为*.c时 编译器将会用C编译器方式编译
*.cpp
  当文件后缀名为*.cpp时 编译器将会用C++编译器方式编译
区别:

解决办法
在需要用到C方式编译的函数前加extern "C"

需要用C方式编译的头文件做如下修改
#pragma once
#ifdef __cplusplus
extern "C"
{
#endif
#include <NTDDK.h> //这里包含需要用C方式编译的头文件
#ifdef __cplusplus
}
#endif


1>errors in directory g:\驱动教程\024_驱动代码中c和c++代码区别\mini_ddk
1>mini_ddk.obj : error LNK2001: unresolved external symbol "struct _ServiceDescriptorTable * KeServiceDescriptorTable" (?KeServiceDescriptorTable@@3PAU_ServiceDescriptorTable@@A)
1>bufferoverflowk.lib(gs_support.obj) : error LNK2019: unresolved external symbol _DriverEntry@8 referenced in function _GsDriverEntry@8
1>sys\i386\ddk_helloworld.sys : error LNK1120: 2 unresolved externals
?DriverEntry@@YGJPAU_DRIVER_OBJECT@@PAU_UNICODE_STRING@@@Z

_DriverEntry@8 //要求格式
?DriverEntry@@YGJPAU_DRIVER_OBJECT@@PAU_UNICODE_STRING@@@Z ?
实例 修改21课的代码 升级到C++编译模式
A、为入口函数 添加extern "C"
B、修改Source文件
C、修改21课的BUG


extern "C" __declspec(naked)  __stdcall   test(int a, int b)


================================

前面已经完成了初级内核代码的编写,已经是一个小巧完整的驱动文件了,本节课要讲解一下理论知识。
编译器认死理儿,载入文件时.C就按C方式.CPP就按C++方式。我们将之前的.C文件改成.CPP,再用BUILD编译一下就发现了一大堆的错误,解决的办法写在教案中.将代码加入头文件再次编译后只剩下3个错误,头文件的错误已经没有了,再看下错误信息(教案中的红字).大概是说函数符号没有找到,另外入口函数也没找到,总体上是LINK链接错误,所以在这两个函数前也要加入extern "C"按照C方式编译.然后看一下mini_ddl.obj里入口函数被替换成了一个长串的入口函数
?DriverEntry@@YGJPAU_DRIVER_OBJECT@@PAU_UNICODE_STRING@@@Z ?
在C方式的时候是原来的入口函数_DriverEntry@8
虽然DDK方式编译成功了,但是在VC++中还是提示错误,这是一个非常经典的错误,我们在 属性页 -> C/C++ -> 高级 ->编译为 里面设置为”默认”或者”编译为C++代码”.

还有在上节课的测试中有一个BUG,因为在卸载函数中是直接恢复代码,应该加上一个判断,如果在未HOOK的情况下就不要再做代码恢复了.比如在虚拟机里测试前面课程的代码在卸载的时候就蓝屏了,而更改后的代码就不会蓝屏了.前面我说了,21课的时候老师没留代码,因为这节课将BUG修改好后才留给我们了.

当然,一般的驱动还是要用C来写,只有用一些高级特性的时候才会用C++来写.

返回列表