阅读:2121回复:12
一个编译器连接问题,请大家帮忙!
小弟在调试驱动程序时碰到了这么一问题:
因为驱动程序中用到了MmGetPhysicalAddress(),而该函数为NTDDK.h中有申明,而在Wdm.h中没有定义,所以我在程序中自己人为地引入了函数申明: NTKERNELAPI PHYSICAL_ADDRESS MmGetPhysicalAddress ( IN PVOID BaseAddress ); 但是,在Build该驱动程序时,编译通过,但是Link时出错,信息如下: --------------------Configuration: P9054 - Win32 Checked-------------------- Compiling... P9054.cpp P9054Device.cpp Linking... P9054Device.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) union _LARGE_INTEGER __stdcall MmGetPhysicalAddress(void *)" (__imp_?MmGetPhysicalAddress@@YG?AT_LARGE_INTEGER@@PAX@Z) .\objchk\i386\P9054.sys : fatal error LNK1120: 1 unresolved externals Error executing link.exe. P9054.sys - 2 error(s), 0 warning(s) 在MSDN中发现,出现该错误(error LNK2001)可能的原因是由于C++与C之间调用命名的差别,按照提示MSDN说法在程序中加入了 extern “C” ,然后再次Build,就出现如下错误信息: --------------------Configuration: P9054 - Win32 Checked-------------------- Compiling... P9054Device.cpp Linking... P9054Device.obj : error LNK2001: unresolved external symbol __imp__MmGetPhysicalAddress@4 .\objchk\i386\P9054.sys : fatal error LNK1120: 1 unresolved externals Error executing link.exe. P9054.sys - 2 error(s), 0 warning(s) 两者的区别在于: 1 => “"__declspec(dllimport) union _LARGE_INTEGER __stdcall MmGetPhysicalAddress(void *)"(__imp_?MmGetPhysicalAddress@@YG?AT_LARGE_INTEGER@@PAX@Z)” 2 => “__imp__MmGetPhysicalAddress@4” 小弟以前一直是做硬件的,对VC不熟,不明白是什么意思,请各位大侠帮忙看看是什么原因,我这样做是否可行? 先谢了! |
|
沙发#
发布于:2004-03-17 20:18
ntoskrnl.lib
|
|
板凳#
发布于:2004-03-17 20:23
arthurtu老兄,你是指需要在VC中加入ntoskrnl.lib库?
|
|
地板#
发布于:2004-03-17 20:29
#pragma comment(lib,"ntoskrnl.lib")
|
|
|
地下室#
发布于:2004-03-17 20:50
肯定是这个的原因
|
|
5楼#
发布于:2004-03-17 21:57
#ifdef __cplusplus
extern "C" { #endif NTKERNELAPI PHYSICAL_ADDRESS MmGetPhysicalAddress ( IN PVOID BaseAddress ); #ifdef __cplusplus } #endif 试试这样 |
|
6楼#
发布于:2004-03-18 08:08
#ifdef __cplusplus 这样不行! 我时试过了,会出现第2种错误 |
|
7楼#
发布于:2004-03-18 10:56
#pragma comment(lib,"ntoskrnl.lib") 是不是在我的源文件中加入#pragma comment(lib,"ntoskrnl.lib")? 我试了,还是会出现第二个错误。 wowocock, 你看还有没有别的原因? |
|
8楼#
发布于:2004-03-18 11:58
#ifdef __cplusplus
extern "C" { #endif NTKERNELAPI PHYSICAL_ADDRESS MmGetPhysicalAddress ( IN PVOID BaseAddress ); #ifdef __cplusplus } #endif 再试。 |
|
9楼#
发布于:2004-03-18 16:00
还是不行啊,如果加入
#ifdef __cplusplus extern "C" { #endif .... #ifdef __cplusplus } #endif 加么就会出现第二种错误,如果不加入,就会出现第一种错误,如果不加入对MmGetPhysicalAddress () 的申明,编译就不能正常通过(找不到该函数) :( |
|
10楼#
发布于:2004-03-18 16:38
PVOID __declspec(naked) MmGetPhysicalAddress(DWORD LineAddress)
{ _asm { mov ecx, LineAddress mov eax, ecx shr eax, 14h and eax, 0FFCh push esi lea esi, [eax+C0300000H] mov edx, [esi] mov eax, edx and ax, 81h ;Juge PS=1 P=1 (PDE .4M Page) cmp al, 81h jz short loc_43855A mov edx, [esi] test dl, 1 ;Juge P=1 (PDE. PDE) jz short loc_43856B test dl, dl ;Juge P=0 PS=0 (PDE) mov eax, ecx js short loc_43855C ;Juge PS=1 (PDE. 4M Page) shr eax, 0Ah and eax, 3FFFFCh sub eax, 40000000h ;same code: add eax,C0000000H mov eax, [eax] test al, 1 ;P=1 (PTE) jz short loc_43856B shr eax, 0Ch loc_438545: ; CODE XREF: .text:00438569j xor edx, edx shld edx, eax, 0Ch shl eax, 0Ch and ecx, 0FFFh add eax, ecx loc_438556: ; CODE XREF: .text:0043856Fj pop esi ret 4 loc_43855A: ; CODE XREF: .text:00438520j;PS=1 P=1 mov eax, ecx loc_43855C: ; CODE XREF: .text:0043852Dj;PS=1 shr eax, 0Ch and eax, 3FFh shr edx, 0Ch add eax, edx jmp short loc_438545 ; ??????????????????????????????????????????????????????????????????????????? loc_43856B: ; CODE XREF: .text:00438527j;P=0 ; .text:00438540j xor eax, eax xor edx, edx jmp short loc_438556 } } [编辑 - 3/18/04 by wowocock] |
|
|
11楼#
发布于:2004-03-18 19:51
哇,wowocock兄果然牛人!
太好了! 不过,下面的一行问号是什么意思? 能否帮助解释一下? :D |
|
12楼#
发布于:2004-03-18 20:49
靠,直接到NTOSKRNL里去反汇编,然后直接拿来用,多好??
|
|
|