happyhhhh2
驱动牛犊
驱动牛犊
  • 注册日期2006-04-11
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分423分
  • 威望66点
  • 贡献值0点
  • 好评度45点
  • 原创分0分
  • 专家分0分
阅读:3992回复:6

关于驱动程序与dll交互的问题,人都折腾疯了!!

楼主#
更多 发布于:2007-06-29 21:49
小弟想在驱动程序编译的时候加入了一个由dll引出的函数一起编译想让其共同完成驱动的生成,仅在passive_level上调用,于是写了下面的两个简单的驱动跟函数验证下行否,结果郁闷了,按照正常的应用程序+连接库的渠道未能通过编译,显示下面信息,还请各位指教为何会如此呀?实在不明白,已经晕了无数次了.
unresolved external symbol "__declspec(dllimport) int __stdcall getlen(int)" (__imp_?getlen@@YGHH@Z) referenced in function "long __stdcall Wdm1Pnp(struct _DEVICE_OBJECT *,struct _IRP *)" (?Wdm1Pnp@@YGJPAU_DEVICE_OBJECT@@PAU

dll里函数极其简单:
int getlen(int size)
{
int b = 2;
b += size;
return b;
}
在驱动里调用地点是pnp中
    int c = getlen(4);
附件名称/大小 下载次数 最后更新
wdmtest.rar (53KB)  27 2007-06-29 21:49
xjtusdbzh
禁止发言
禁止发言
  • 注册日期2005-04-22
  • 最后登录2018-07-10
  • 粉丝1
  • 关注0
  • 积分-812分
  • 威望44点
  • 贡献值1点
  • 好评度124点
  • 原创分1分
  • 专家分0分
沙发#
发布于:2007-06-30 11:42
用户被禁言,该主题自动屏蔽!
happyhhhh2
驱动牛犊
驱动牛犊
  • 注册日期2006-04-11
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分423分
  • 威望66点
  • 贡献值0点
  • 好评度45点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2007-07-01 02:02
我这个应该是编译的问题,但我自己解决不了,郁闷啊
tfp_unix
驱动小牛
驱动小牛
  • 注册日期2003-07-10
  • 最后登录2008-01-25
  • 粉丝0
  • 关注0
  • 积分639分
  • 威望75点
  • 贡献值0点
  • 好评度72点
  • 原创分0分
  • 专家分0分
地板#
发布于:2007-08-28 23:20
try try   "extern"
guenli
驱动牛犊
驱动牛犊
  • 注册日期2009-12-18
  • 最后登录2010-02-19
  • 粉丝0
  • 关注0
  • 积分61分
  • 威望611点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2010-02-13 13:23
关注一下!
springmydriver
驱动牛犊
驱动牛犊
  • 注册日期2012-04-24
  • 最后登录2012-05-09
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望41点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2012-05-09 16:51
你的这个getlen(int)函数看起来是你自己写的函数而不是调用的操作系统的API,这样你的驱动在调用DLL中的这个函数时岂不是要切换到用户模式去运行你的getlen(int)函数?
 
请参考下面的文章:
内 核模式中 DLL 的基本问题是 DLL 是否调用任何用户模式代码。如果 DLL 包含除本地内核 API 调用之外的任何内容,那么如果您在编译时试图将驱动程序与其链接,就会产生链接程序错误(内核根本不会加载它)。显然,编译成 Win32 库的 DLL 属于这种类别。即使您在 DLL 源代码中避免进行显式用户模式 API 调用,编译器仍然会在进行堆栈检查、溢出检查和类似操作时经常生成隐式的用户模式支持调用。所以,在 Windows 用户模式开发环境(例如 Visual Studio)中编译的任何 DLL 都不能在内核模式中使用。
 
您应该做什么?
 
使用 DDK 编译环境编译导出驱动程序。导出驱动程序是一个内核模式 DLL,为其他要调用的驱动程序提供例程。与任何标准驱动程序一样,导出驱动程序只包含解析内核模式函数的例程。但是,与标准驱动程序不同的是,导出驱动程序不接受 IRP 或占据驱动程序堆栈中的空间,它也不会被认为是一种系统服务。
 
您可以将任何标准驱动程序编译成导出驱动程序,在以常规的方式加载后它将作为标准驱动程序运行,并且还导出其他驱动程序可以调用的函数。但是,如果您只是想要编写库的内核模式等价物,那么您可以忽略完整的驱动程序所需的许多元素。导出驱动程序至少必须有一个 DriverEntry 例程;这可以是一个空的存根来满足编译脚本的要求,导出驱动程序的 DriverEntry 决不会被即插即用调用。导出驱动程序还应该具有标准入口点和卸载例程(DllInitialize 和 DLLUnload),从而操作系统可以跟踪导出驱动程序的函数被其它驱动程序导入的次数,并在最后一次调用驱动程序卸载时卸载导出驱动程序。
 
您 可以通过在导出驱动程序源代码中使用 DECLSPEC_EXPORT 宏声明函数将其导出,或者您可以采用更简单的方法,那就是在模块定义文件 (.def) 中将这些函数列出为导出。(即使您使用 DECLSPEC_EXPORT,您的 .def 文件仍然至少必须包含 DllInitialize 和 DLLUnload,这样您才可以将这些函数标记为 PRIVATE。)
 
在驱动程序的 sources 文件中,将 TARGETTYPE 设置为 EXPORT_DRIVER 并且将 DLLDEF 设置为您的 .def 文件的路径,然后编译驱动程序。编译过程生成一个扩展名为 .lib 的导出库和一个扩展名为 .sys 的导出驱动程序。.sys 文件是您的内核模式 DLL。
 
导出驱动程序的静态链接本质上与用户模式 DLL 相同:将导出驱动程序库添加到将要调用库的驱动程序的目标库列表。在调用驱动程序的源代码中,使用 DECLSPEC_IMPORT 宏来声明它将调用的函数。(还应使用 ntdef.h 中定义的 EXTERN_C 来避免调用中出现任何不希望的名称修饰。)将导出驱动程序 .sys 文件安装到 %windir%\system32\drivers 目录中。它将在任何其它驱动程序第一次调用它时被加载。
 
动态链接稍微复杂一些,因为没有 GetProcAddress 的内核模式等价物。(MmGetSystemRoutineAddress 与其类似,但是它只从 Ntoskrnl.exe 或 HAL 动态解析导出。)这是用于动态链接到导出驱动程序的一些技术:
 
•        
在导出驱动程序中,定义一个 I/O 控制码 (IOCTL) 来实例化一个类并返回一个其它驱动程序可以用来以常规方式调用接口对象上方法的接口指针。该类应该提供一个用于释放对象的方法,并且头文件应该只包含纯粹的抽象方法。
 
•        
设计导出驱动程序来导出直接调用接口,以响应来自其它驱动程序的 IRP_MN_QUERY_INTERFACE 请求。
znsoft
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2023-10-25
  • 粉丝300
  • 关注6
  • 积分910分
  • 威望14796点
  • 贡献值7点
  • 好评度2410点
  • 原创分5分
  • 专家分100分
  • 社区居民
  • 最爱沙发
  • 社区明星
6楼#
发布于:2012-05-09 17:02
驱动可以调用dll,但是必须是内核模式dll
你可以参看站上的教程,或者搜索内核模式动态库
写法跟驱动差不多,导出一个函数,由驱动调用。
普通的用户模式的dll不可以直接调用,当然,除非你有hack手段。从你的提问来看,显然不具备这样的能力,而且这样的用法也是不推荐的。

请用正规手段:内核模式动态库
http://www.zndev.com 免费源码交换网 ----------------------------- 软件创造价值,驱动提供力量! 淡泊以明志,宁静以致远。 ---------------------------------- 勤用搜索,多查资料,先搜再问。
游客

返回顶部