阅读:4130回复:6
关于驱动程序与dll交互的问题,人都折腾疯了!!
小弟想在驱动程序编译的时候加入了一个由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); |
|
|
沙发#
发布于:2007-06-30 11:42
用户被禁言,该主题自动屏蔽! |
|
板凳#
发布于:2007-07-01 02:02
我这个应该是编译的问题,但我自己解决不了,郁闷啊
|
|
地板#
发布于:2007-08-28 23:20
try try "extern"
|
|
地下室#
发布于:2010-02-13 13:23
关注一下!
|
|
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 请求。 |
|
6楼#
发布于:2012-05-09 17:02
驱动可以调用dll,但是必须是内核模式dll
你可以参看站上的教程,或者搜索内核模式动态库 写法跟驱动差不多,导出一个函数,由驱动调用。 普通的用户模式的dll不可以直接调用,当然,除非你有hack手段。从你的提问来看,显然不具备这样的能力,而且这样的用法也是不推荐的。 请用正规手段:内核模式动态库 |
|
|