CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  进程/线程/DLL

一个DLL入门问题(在线等)

楼主zhrwolf1(清风)2006-01-10 11:29:38 在 VC/MFC / 进程/线程/DLL 提问

我刚学习使用DLL,   在DLL定义了一个函数如下,编译通过  
  __declspec(dllexport)     int   GetIntValue(int   i)  
  {  
  return     i+1000;  
  }  
   
  但在调DLL中这个函数时就报错  
  int   b=GetIntValue(100);  
   
  错误:  
  KeyHookDlg.obj   :   error   LNK2001:   unresolved   external   symbol   "int   __cdecl   GetIntValue(int)"   (?GetIntValue@@YAHH@Z)  
   
  请问各位老大,这到底怎么了?    
  问题点数:100、回复次数:36Top

1 楼goodboyws(深夜不眠者(VCMVP))回复于 2006-01-10 11:33:36 得分 0

GetIntValue定义的和DLL里不一致,要看你在ExE里是怎么用的Top

2 楼zhrwolf1(清风)回复于 2006-01-10 11:35:56 得分 0

to   goodboyws(深夜不眠者):  
  我是加载了DLL里的.h文件的,定义肯定是一样的Top

3 楼laiyiling(陌生人[MVP])回复于 2006-01-10 11:47:27 得分 10

没有添加DLL的LIB文件,如果不加这个文件,可以动态加载,具体参考:  
  extern   "C"   __declspec(dllexport)   void   Show()  
  {  
  //。。。。。。//  
  }  
   
  typedef   void   (WINAPI   *   TESTDLL)();  
   
   
  HINSTANCE   hmod;  
  hmod   =   ::LoadLibrary   ("mfcdll.dll");  
  if(hmod==NULL)  
  {  
  AfxMessageBox("Fail");  
  }  
  TESTDLL   lpproc;  
  lpproc   =   (TESTDLL)GetProcAddress   (hmod,"Show");  
  if(lpproc!=(TESTDLL)NULL)  
  (*lpproc)();  
  FreeLibrary(hmod);  
  Top

4 楼laiyiling(陌生人[MVP])回复于 2006-01-10 11:48:46 得分 10

要加入lib文件的位置在  
  project->project   settings->link->object/libray   modules   下面Top

5 楼zhrwolf1(清风)回复于 2006-01-10 11:49:29 得分 0

to   laiyiling(【CSDN●】):  
  我是用静态加载的,   直接加了.lib文件  
  定义函数时也试过加extern   "C"   ,结果还是一样,  
  在测试调用DLL程序中编译就报同样的错Top

6 楼zhrwolf1(清风)回复于 2006-01-10 11:52:03 得分 0

说明一下,我的DLL是MFC   AppWizard(DLL),  
  一开始函数没传参数时还调用成功过,后来加了传入参数后就报错了,  
  然后我把参数去掉还是报错,我是个菜鸟,   这样就更不明白了.  
  Top

7 楼goodboyws(深夜不眠者(VCMVP))回复于 2006-01-10 12:06:22 得分 10

DLL里的.h  
  是不是  
  __declspec(dllimport)写成  
  __declspec(dllexport)了Top

8 楼wangk(倒之)回复于 2006-01-10 12:09:39 得分 10

工程里加入一个.def文件  
  内容是:  
  ;   ExcuteScript.def   :   Declares   the   module   parameters   for   the   DLL.  
   
  EXPORTS  
          ;   Explicit   exports   can   go   here  
  DllMain @1  
  GetIntValue @2  
   
  重新编译后,就能用GetProcAddress   或者头文件直接声明。Top

9 楼zhrwolf1(清风)回复于 2006-01-10 12:17:19 得分 0

to     goodboyws(深夜不眠者)   :  
  如果写成   __declspec(dllimport),   在DLL那里就编译不能过Top

10 楼zhrwolf1(清风)回复于 2006-01-10 12:21:01 得分 0

to   wangk(倒之)   (   )   :  
  我按你说的加了def文件,   可还是报同样错误Top

11 楼zhrwolf1(清风)回复于 2006-01-10 12:22:12 得分 0

我吃完饭就来Top

12 楼goodboyws(深夜不眠者(VCMVP))回复于 2006-01-10 12:37:37 得分 0

两个不能一样,DLL里用  
  __declspec(dllexport)  
  exe里用__declspec(dllimport)  
  Top

13 楼zhrwolf1(清风)回复于 2006-01-10 12:52:17 得分 0

to   goodboyws(深夜不眠者):  
        我是静态加载DLL,直接将DLL的.h文件加到工程里来了,    
  我把这个.h里的函数定义改成dllimport了,还是报错:  
  KeyHookDlg.obj   :   error   LNK2001:   unresolved   external   symbol   "__declspec(dllimport)   int   __cdecl   GetIntValue(void)"   (__imp_?GetIntValue@@YAHXZ)Top

14 楼dahai_2002( 编程浪子)回复于 2006-01-10 13:00:33 得分 0

GetIntValue函数所在的dll库没有被加载,你可以隐式或显式地加载它.    
  你现在已经加了.h头文件,   但根据提示的犯错误信息应该是没找到dll,   可以在项目设置的link选项卡上加上这个库.Top

15 楼zhrwolf1(清风)回复于 2006-01-10 13:02:59 得分 0

to     dahai_2002(编程浪子)   ;  
  我在link选项卡上加上已经加了.lib文件了Top

16 楼zhrwolf1(清风)回复于 2006-01-10 13:04:48 得分 0

我本来是下载一个DLL例子,   一开始在上面加函数再测试调用都没问题,  
  而现在问题更严重了,   我只把原来的函数改个名子再调用都会报同样的错误.  
  本来这个函数是可以调用的,   这是怎么回事?Top

17 楼kugou123(酷狗)(彪悍的人生,不需要解释 www.xiaozhou.net)回复于 2006-01-10 13:15:51 得分 10

#pragma   comment(lib,"**.lib")Top

18 楼zhrwolf1(清风)回复于 2006-01-10 13:31:47 得分 0

TO   kugou123(酷狗)(君看一叶舟,出没风波里)   :  
  我在project的Link中加了Top

19 楼john_c_cooper(john_c_cooper)回复于 2006-01-10 14:43:00 得分 10

利用extern   “C”修饰来防止输出名称被改变  
  extern   "C"   __declspec(dllexport)   int   GetIntValue(int   i)  
  因为vc的编译器按照c++的标准把GetIntValue的函数名改了。  
  加extern   “C”就可以了。  
  照理说这样也可以的。  
  回复人:   wangk(倒之)   (   )   信誉:102     2006-1-10   12:09:39     得分:   0      
     
     
         
  工程里加入一个.def文件  
  内容是:  
  ;   ExcuteScript.def   :   Declares   the   module   parameters   for   the   DLL.  
   
  EXPORTS  
          ;   Explicit   exports   can   go   here  
  DllMain@1  
  GetIntValue@2  
   
  重新编译后,就能用GetProcAddress   或者头文件直接声明。  
   
  你可以参考一下windows程序设计里面关于dll的内容。  
     
  Top

20 楼john_c_cooper(john_c_cooper)回复于 2006-01-10 14:52:04 得分 10

看样子楼主在研究hook的东西。  
  引用别人的一篇文章  
  利用钩子函数捕获Windows鼠标动作  
  发表人:alexclark   |   发表时间:   2005年三月10日,   17:39  
   
  我们知道,Windows系统是建立在消息传递机制基础上的,几乎所有的程序活动都由消息来驱动。Windows的钩子机制可以看作是一个消息中转站,控制系统发出消息的处理和传递,利用钩子,我们可以截获系统发给应用程序的消息,经过处理后决定是否将消息再发给下一个应用程序。    
   
  利用钩子的这一特性,我们可以创建一个监控程序,用来收集和控制系统发出的消息。    
   
     
   
  ■编制Windows钩子程序    
   
     
   
  编制Windows的钩子程序,需要用到几个SDK中的API函数。下面列出这几个函数的原型及说明:    
   
  HHOOK   SetWindowsHookEx(   int   idHook,HOOK_PROC   lpfn,HINSTANCE   hMod,DWORD   dwThreadID);    
   
  参数说明如下:    
   
  idHook:钩子的类型    
   
  lpfn:钩子处理函数地址    
   
  hMod:包含钩子函数的模块句柄    
   
  dwThreadID:钩子的监控线程    
   
  函数说明:函数将在系统中挂上一个由idHook指定类型的钩子,监控并处理相应的特定消息。    
   
  BOOL   UnhookWindowsHookEx(HHOOK   hhk);    
   
  函数说明:函数将撤销由hhk指定的钩子。    
   
  LRESULT   CallNextHookEx(   HHOOK   hhk,   int   nCode,WPARAM   wParam,LPARAM   lParam   );    
   
  函数说明:函数将消息向下传递,下一个钩子处理将截获这一消息。    
   
  由于钩子的处理涉及到模块及进程间的数据地址问题,一般情况是把钩子整合到一个动态链接库(DLL)中,并设立一个全局数据共享数据段,以存贮一些全局变量,保留上次钩子消息事件发生时的状态。全局共享数据段可以用如下的格式定义:    
   
  #pragma   data_seg("PublicData")    
   
  HHOOK   hhook=NULL;    
   
  //全局共享数据    
   
  #pragma   data_seg()    
   
  本文的范例程序演示了如何编制一个鼠标钩子(WH_MOUSE)程序,其它类型的钩子程序的编写过程与范例程序类似。    
   
     
   
  ■范例程序的建立与代码分析    
   
     
   
  建立钩子程序时需要把钩子处理整合到动态链接库中,所以例程中需要建立两个Project。    
   
  1.建立钩子处理动态链接库    
   
  (1)   选择MFC   AppWizard(DLL)创建一个新Project,命名为“Spy”。    
   
  (2)   选择MFC   Extension   DLL类型。    
   
  (3)创建一个新的头文件,命名为“Hook.h”,修改它的代码如下:    
   
  extern   "C"   LRESULT   CALLBACK   MouseProc(int   code,    
   
  WPARAM   wParam,LPARAM   lParam);   //钩子处理函数    
   
  extern   "C"   BOOL   WINAPI   StartHook();    
   
  //启动钩子函数    
   
  extern   "C"   BOOL   WINAPI   StopHook();    
   
  //撤销钩子函数    
   
  extern   "C"   int   WINAPI   GetResult();    
   
  //取得鼠标单击次数的函数    
   
  (4)修改Spy.cpp程序代码如下:    
   
  #include   "stdafx.h"    
   
  #include   〈afxdllx.h〉    
   
  #include   "spyhook.h"    
   
  ……    
   
  //省略部分机器生成代码    
   
  #pragma   data_seg("PublicData")    
   
  //定义全局数据段    
   
  HHOOK   hhook=NULL;    
   
  //钩子句柄    
   
  HINSTANCE   pInstance=NULL;    
   
  //钩子模块句柄    
   
  UINT   MouseClick=0;    
   
  //记录鼠标单击次数的变量    
   
  #pragma   data_seg()    
   
  ……    
   
  //省略部分机器生成代码    
   
  extern   "C"   int   APIENTRY    
   
  DllMain(HINSTANCE   hInstance,   DWORD   dwReason,   LPVOID   lpReserved)    
   
  {    
   
  if   (dwReason   =   =   DLL_PROCESS_ATTACH)    
   
  {……    
   
  //省略部分机器生成代码    
   
  new   CDynLinkLibrary(SpyDLL);    
   
  pInstance=hInstance;    
   
  //取得模块句柄    
   
  }    
   
  else   if   (dwReason   =   =   DLL_PROCESS_DETACH)    
   
  {    
   
  TRACE0("SPY.DLL   Terminating!n");    
   
  AfxTermExtensionModule(SpyDLL);    
   
  }    
   
  return   1;    
   
  }    
   
  extern   "C"   LRESULT   CALLBACK   MouseProc(int   code,WPARAM   wParam,LPARAM   lParam)    
   
  //钩子处理函数    
   
  {    
   
  if   (code   〈   0)    
   
  //若code〈0,则直接调用CallNextHookEx返回    
   
  return   CallNextHookEx(hhook,   code,   wParam,   lParam);    
   
  if(wParam=   =WM_LBUTTONDOWN)    
   
  {MouseClick++;    
   
  //记录鼠标单击次数    
   
  }    
   
  return   CallNextHookEx(hhook,   code,   wParam,lParam);    
   
  }    
   
  extern   "C"   BOOL   WINAPI   StartHook()    
   
  //启动钩子函数    
   
  {    
   
  hhook=SetWindowsHookEx(WH_MOUSE,MouseProc,pInstance,0);    
   
  //挂上钩子    
   
  if(hhook!=NULL)    
   
  return   TRUE;    
   
  else   return   FALSE;    
   
  }    
   
  extern   "C"   BOOL   WINAPI   StopHook()    
   
  //撤销钩子函数    
   
  {    
   
  return   UnhookWindowsHookEx(hhook);    
   
  //撤销钩子    
   
  }    
   
  extern   "C"   int   WINAPI   GetResult()    
   
  //返回鼠标单击次数    
   
  {    
   
  return   MouseClick;    
   
  }    
   
  (5)修改Spy.def程序代码如下:    
   
  LIBRARY   "SPY"    
   
  DESCRIPTION   'SPY   Windows   Dynamic   Link   Library'    
   
  EXPORTS    
   
  StartHookb   @1    
   
  StopHook   @2    
   
  GetResult   @3    
   
  (6)编译Project,生成Spy.dll文件和Spy.Lib文件。    
   
  2.建立使用钩子的应用程序    
   
  (1)   生成一个单文档的可执行文件(EXE)的Project。    
   
  (2)   修改资源中的主选单,增加一个选单项“监控”,下有三个子选单项,分别为“启动”、“撤销”和“取出”。    
   
  (3)   在Project中加入Spy.Lib文件和Hook.h文件。    
   
  (4)   分别修改“启动”、“撤销”和“取出”选单项的Command响应函数如下:    
   
  #include   "hook.h"    
   
  ……//省略部分机器生成代码    
   
  void   CMainFrame::OnStartSpy()    
   
  //“启动”选单项的响应函数    
   
  {    
   
  StartHook();    
   
  }    
   
  void   CMainFrame::OnReleaseSpy()    
   
  //“撤销”选单项的响应函数    
   
  {    
   
  StopHook();    
   
  }    
   
  void   CMainFrame::OnGet()    
   
  //“取出”选单项的响应函数    
   
  {    
   
  int   Result=GetResult();    
   
  char   buffer[40];    
   
  wsprintf(buffer,"在程序运行期间,你共单击鼠标%d次",Result);    
   
  ::MessageBox(this-〉m_hWnd,buffer,"Message",MB_OK);    
   
  }    
   
  编译这个Project,并把Spy.dll放到生成的可执行文件目录下,便可运行程序。    
   
  运行时,选择“监控”选单中的“启动”选单项,钩子便开始工作,监视鼠标的活动情况;选择“撤销”选单项,系统便撤销钩子;选择“取出”选单项,程序便报告在监控期间,用户单击鼠标左键的次数。    
  Top

21 楼john_c_cooper(john_c_cooper)回复于 2006-01-10 14:56:35 得分 0

这2篇也不错  
  http://www.microsoft.com/china/community/program/originalarticles/techdoc/hook.mspx  
  http://dev.csdn.net/develop/article/60/60468.shtm  
  其实写hook不一定要用dll的。函数写在exe里也行的(如果你不是真的为了写木马)。  
  Top

22 楼handsomerun(毛毛)回复于 2006-01-10 16:01:34 得分 0

楼主问题解决了吗  
   
  很奇怪,这个错误是很常见的那种lib文件没有导入的错误  
  或者实现不一致那种的  
   
  但是你肯定是导入的阿,呵呵  
   
  Top

23 楼zhrwolf1(清风)回复于 2006-01-10 16:03:17 得分 0

谢谢各位的资料  
  各位大虾可能是没看到中间部分,   我想知道的是我的错误是原因产生的,  
  怎么样可以解决这个错误.  
  我只是想学习使用DLL(   MFC   AppWizard(DLL))  
  Top

24 楼CCED136(夜林箭)回复于 2006-01-11 09:27:13 得分 10

在   DLL   中,这样就可以了  
   
  __declspec(dllexport)     extern   "C"     int   WINAPI   GetIntValue(int   i)  
  {  
  return     i+1000;  
  }  
   
   
  在   EXE   中,这样申明就可以了  
   
  __declspec(dllimport)   extern   "C"   int   WINAPI   GetIntValue(int   i);  
  Top

25 楼zhrwolf1(清风)回复于 2006-01-11 10:33:54 得分 0

我再试试,   只要不是MFC的那种DLL一般都没出这问题.Top

26 楼taianmonkey()回复于 2006-01-11 10:40:00 得分 0

__declspec(dllexport)   WINAPI   int   GetIntValue(int   i)  
  {  
  return     i+1000;  
  }Top

27 楼wujangjang(武林外史)回复于 2006-01-11 10:47:25 得分 0

学习中Top

28 楼zhrwolf1(清风)回复于 2006-01-11 10:58:52 得分 0

to   CCED136(夜林箭)   :  
  我按你说的写的,   但是DLL编译都不能通过,   错误如下:   这是怎么回事?  
   
  :\documents   and   settings\zhanghr\my   documents\dll测试\mfc_dll\mfc_dll.h(27)   :   error   C2059:   syntax   error   :   'string'  
  c:\documents   and   settings\zhanghr\my   documents\dll测试\mfc_dll\mfc_dll.h(27)   :   error   C2238:   unexpected   token(s)   preceding   ';'  
  Top

29 楼CCED136(夜林箭)回复于 2006-01-11 11:52:18 得分 10

在   VC   中,语句顺序可能需要变一下:  
   
  在   DLL   中(在   cpp   文件中),这样就可以了  
   
  extern   "C"     __declspec(dllexport)     int   WINAPI   GetIntValue(int   i)  
  {  
  return     i+1000;  
  }  
   
   
  在   EXE   中,这样申明就可以了(在.h   中加入下列语句)  
   
  extern   "C"     __declspec(dllimport)     int   WINAPI   GetIntValue(int   i);  
   
  Top

30 楼CCED136(夜林箭)回复于 2006-01-11 11:57:13 得分 10

在撰写   dll   时,   如果你要将导出和导入写到   .h   文件中,则:  
  .h   文件中应该这样写:  
   
  extern   "C"     __declspec(dllexport)     int   WINAPI   GetIntValue(int   i);  
   
  .cpp   文件中的则应该为:  
   
  int   WINAPI   GetIntValue(int   i)  
  {  
          return     i+1000;  
  }  
  Top

31 楼WilliamJ(威廉J)回复于 2006-01-11 13:40:05 得分 0

连接出错和.DLL文件没有一点关系,连接时要用到.LIB文件,你一定要将其包括进去。Top

32 楼zhrwolf1(清风)回复于 2006-01-11 14:01:22 得分 0

我已经在工程里加入.lib文件了Top

33 楼stone_817(stone_817)回复于 2006-01-11 17:59:37 得分 0

给你个提示,在project->setting中,在c++项中选择code   generation   中更改calling   convention   即可。我设置的为stdcall,我估计你一一样。Top

34 楼hushuangyan74()回复于 2006-01-11 19:16:32 得分 0

多试试Top

35 楼fatacy(fatacy)回复于 2006-01-11 22:51:11 得分 0

看错误报告应该是   命名规约不匹配问题.用夜林雨的声明方式就好了Top

36 楼zhrwolf1(清风)回复于 2006-01-13 10:11:04 得分 0

谢谢大家,   不知道怎么回事,我重新做了几个现在终于没出错了Top

相关问题

  • dll入门问题。
  • 入门问题:怎样在DLL中使用CString类???
  • 请教:DLL入门知识
  • 还没有入门 在线等待???
  • 入门级的问题,在线等待
  • 入门级问题,在线等待.
  • 高分求入门问题,在线等!
  • ******DELPHI入门问题*******(关于DLL)
  • 还没入门的问题,在线等待,立刻给分。
  • sql server 入门的一个问题,在线等待

关键词

  • 函数
  • 文件
  • dll
  • 鼠标
  • 编译
  • 代码
  • 钩子
  • getintvalue
  • hhook
  • 撤销

得分解答快速导航

  • 帖主:zhrwolf1
  • laiyiling
  • laiyiling
  • goodboyws
  • wangk
  • kugou123
  • john_c_cooper
  • john_c_cooper
  • CCED136
  • CCED136
  • CCED136

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo