wei_ziyong
驱动牛犊
驱动牛犊
  • 注册日期2003-12-31
  • 最后登录2010-04-30
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望16点
  • 贡献值0点
  • 好评度16点
  • 原创分0分
  • 专家分0分
阅读:1473回复:16

动态连接库错误!!

楼主#
更多 发布于:2004-06-02 14:34
我在win32动态连接库中写了一个函数,功能是打开驱动程序的句柄,
动态库和应用程序编译都是正确的。
   然后,在一个对话框程序中调用这个动态连接库中的这个函数可时出现了如下的错误,说某个内存地址不能够为写,请问高手们这应该如何解决阿? :o
snowStart
驱动老牛
驱动老牛
  • 注册日期2004-04-06
  • 最后登录2011-06-02
  • 粉丝0
  • 关注0
  • 积分95分
  • 威望19点
  • 贡献值177点
  • 好评度1点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-06-02 15:38
这种情况一般是你引用的指针为空,或没初始化,或超出了你申请的内存范围,
你可以在该对话框中点击取消,进入调试程序状态,以便定位具体哪一行,哪个语句,哪个函数出错
学习,关注,交流中... [email=fengyu@163.com]Email:snowstarth@163.com[/email] [url]http://bbs.zndev.com/?a=snowStart[/url]
walkonthesky
驱动中牛
驱动中牛
  • 注册日期2003-11-26
  • 最后登录2012-11-06
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望20点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-06-02 16:30
指针为空,ASSERT通不过,而且不会出现can not be writen类错误;
如果指针没有初始化,编译器会出现warning C4700: local variable used without having been initialized的警告;
只有第三种情况才可能出现顶楼说的那种编译完全通过,而运行出错的情况。
[img]http://www.driverdevelop.com/forum/upload/walkonthesky/2004-07-08_2004-07-07_b847.gif[/img]
wei_ziyong
驱动牛犊
驱动牛犊
  • 注册日期2003-12-31
  • 最后登录2010-04-30
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望16点
  • 贡献值0点
  • 好评度16点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-06-02 19:25
你们说的都不是,相同的代码在动态连接库的不同的函数中运行,一个就没有错误,而另外一个就要报错。
snowStart
驱动老牛
驱动老牛
  • 注册日期2004-04-06
  • 最后登录2011-06-02
  • 粉丝0
  • 关注0
  • 积分95分
  • 威望19点
  • 贡献值177点
  • 好评度1点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-06-02 20:02
自己的程序跟踪一下不就知道错误原因了吗
学习,关注,交流中... [email=fengyu@163.com]Email:snowstarth@163.com[/email] [url]http://bbs.zndev.com/?a=snowStart[/url]
wei_ziyong
驱动牛犊
驱动牛犊
  • 注册日期2003-12-31
  • 最后登录2010-04-30
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望16点
  • 贡献值0点
  • 好评度16点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-06-02 20:21
前辈,能够说详细一点么,
怎么跟踪阿?指点一下吗我的错误实在是很奇怪的下面我把我的源代码也
贴出来请大家帮我看看
wei_ziyong
驱动牛犊
驱动牛犊
  • 注册日期2003-12-31
  • 最后登录2010-04-30
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望16点
  • 贡献值0点
  • 好评度16点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-06-02 20:25
我的DLL和对话框程序编译时都没有错误,和警告
Test3()是我在动态连接库中定义的,OnButton2()是对话框程序中定义的,
用来调用Tes3()的。
void CTestDlg::OnButton2()
{
Test3();
}

DLL的引出头文件LINK.H是这样定义的:


#ifdef MYLIBAPI
#else
#define MYLIBAPI extern \"C\" __declspec(dllimport)
#endif


MYLIBAPI BOOL LoadDSPFile(char* pFileName);
MYLIBAPI BOOL Test3();

LINK.CPP是这样定义的:

#include \"windows.h\"
#define MYLIBAPI extern \"C\" __declspec(dllexport)
#include \"Link.h\"

BOOL OpenDevice();
MYLIBAPI BOOL LoadDSPFile(char* pFileName)
{
if(OpenDevice())
MessageBox(NULL,\"ok\",\"\",MB_OK);
else
MessageBox(NULL,\"Fail\",\"\",MB_OK);
return true;
}

MYLIBAPI BOOL Test3()
{
OpenDevice();
return true;
}

OpenDevice() 函数在DLL中是这样定义的:
(这个其实是DriverStudio 自动生成(OpenByIntf.cpp)的我没有做过任何的改动)


#include <stdlib.h>
#include <windows.h>
#include <winioctl.h>
#include <devintf.h> // DriverWorks

// OpenByInterface
//
// Opens the nth device found with the given interface class

HANDLE OpenByInterface(
GUID* pClassGuid, // points to the GUID that identifies the interface class
DWORD instance, // specifies which instance of the enumerated devices to open
PDWORD pError // address of variable to receive error status
)
{
HANDLE hDev;
CDeviceInterfaceClass DevClass(pClassGuid, pError);

if (*pError != ERROR_SUCCESS)
return INVALID_HANDLE_VALUE;

CDeviceInterface DevInterface(&DevClass, instance, pError);

if (*pError != ERROR_SUCCESS)
return INVALID_HANDLE_VALUE;

hDev = CreateFile(
DevInterface.DevicePath(),
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);

if (hDev == INVALID_HANDLE_VALUE)
*pError = GetLastError();

return hDev;
}




附件名称/大小 下载次数 最后更新
2004-06-02_源代码.rar (2699KB)  2
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
7楼#
发布于:2004-06-02 21:04
你跟踪看看,估计是应用层的问题。
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
wei_ziyong
驱动牛犊
驱动牛犊
  • 注册日期2003-12-31
  • 最后登录2010-04-30
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望16点
  • 贡献值0点
  • 好评度16点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2004-06-02 22:34
这个肯定是应用的问题,但是,就是不知道应该如何去跟踪,主要的
代码在动态连接库中,无法跟进dll的嘛,有没有其他的办法?
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
9楼#
发布于:2004-06-02 22:59
可以在DLL中下断点的,VC就可以作到,无须SOFTICE
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
wei_ziyong
驱动牛犊
驱动牛犊
  • 注册日期2003-12-31
  • 最后登录2010-04-30
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望16点
  • 贡献值0点
  • 好评度16点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2004-06-02 23:12
我在dll中设置过断点,但是然后执行程序,提示说 dll中社的断点
所在行是无效的,执行程序是也看不出什么
walkonthesky
驱动中牛
驱动中牛
  • 注册日期2003-11-26
  • 最后登录2012-11-06
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望20点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2004-06-03 09:16
好久没有看到这么好的问题了
[img]http://www.driverdevelop.com/forum/upload/walkonthesky/2004-07-08_2004-07-07_b847.gif[/img]
walkonthesky
驱动中牛
驱动中牛
  • 注册日期2003-11-26
  • 最后登录2012-11-06
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望20点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2004-06-03 10:14
你的问题我找到了
在C专区的那个帖子里面我给了你回复
[img]http://www.driverdevelop.com/forum/upload/walkonthesky/2004-07-08_2004-07-07_b847.gif[/img]
wei_ziyong
驱动牛犊
驱动牛犊
  • 注册日期2003-12-31
  • 最后登录2010-04-30
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望16点
  • 贡献值0点
  • 好评度16点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2004-06-03 13:50
感谢你们的帮助walkonthesky,snowStart我已经把分数都给你们了。还有所有回复过我帖子的朋友我都给了分了!谢谢。原来,把自己遇到的问题贴出来,是这么的有帮助,希望能够有机会和大家多交流。
我的联系方式:
wei_ziyong@163.com
QQ:44176254

为了感谢大家对我的帮助我把我的问题的错误发表出来:

HANDLE OpenByInterface(
GUID* pClassGuid, // points to the GUID that identifies the interface class
DWORD instance, // specifies which instance of the enumerated devices to open
PDWORD pError )
其实,错误的原因是上面的这个OpenByInterface()函数的第三个参数
引起的。因为第三个参数是个指针PDWORD类型,所以当调我们用这个函数时,传递的给他的第三个参数都是这样定义的(当然这只是一般的常用的方式中的一种):
Test()
{
   PDWORD pErr;
   OpenByInterface(,,pErr);
}
当然,也可以这样调用:
Test()
{
   PDWORD pErr=ERROR_SUCCESS;
   OpenByInterface(,,pErr);
}
在这里,如果是采用上面的任何的一种方式,给那个函数传递第三个参数肯定是要出现上面我遇到的错误;但是如果是采用下面的这种方式给函数传递第三个参数(而且也是唯一的能够正确的调用这个函数的方式,基本上别无他法,当然除了引用哈):
Test()
{
   DWORD Err=ERROR_SUCCESS;
   OpenByInterface(,,Err);
}
这样调用就是正确的。原因是这样的:
这要看这个函数的内部代码是怎样的使用这个参数的。
HANDLE OpenByInterface(
GUID* pClassGuid, // points to the GUID that identifies the interface class
DWORD instance, // specifies which instance of the enumerated devices to open
PDWORD pError // address of variable to receive error status
)
{
HANDLE hDev;
CDeviceInterfaceClass DevClass(pClassGuid, pError);

if (*pError != ERROR_SUCCESS)
return INVALID_HANDLE_VALUE;
......................

看到这一段了吗,有个*pError方式的调用,直接去访问pError这个地址
的这个地址。如果传递给他的参数是这样定义的话:PDWORD pError;
他就回把pError的值作为内存地址去访问,比如把pError=ERROR_SUCCESS;而ERROR_SUCCESS的直在WINDOWS里是0,这样当程序运行到if (*pError != ERROR_SUCCESS)这里时,就去访问内存地址为0x00000000的单元,这样出现我遇到的错误了。而使用这方式
DWORD Err=ERROR_SUCCESS;
   OpenByInterface(,,Err);
调用,程序执行到
if (*pError != ERROR_SUCCESS)
    return INVALID_HANDLE_VALUE;
这里就不是对地址为0x00000000的地址空间进行访问了。
而只是对Err变量的地址空间进行访问了,而变量的地址空间是系统分配的是合法的地址。
说到这里大家都应该清楚了把,这就是这个错误的真正的原因。
    不过,我还是又有了一个新的疑问,为什么把参数定义为指针PDWORD类型传递是合符语法的规则的啊,怎么会导致上面的哪个错误啊,与自己使用指针的想法恰恰相反了?写到这里我突然明白了这只是指针如何进行初使话的问题。终于彻底想通了。

上面的情况大家可以用我的代码实验。旧可以 看出结果了。再次,感谢大家赐予的灵感!!
walkonthesky
驱动中牛
驱动中牛
  • 注册日期2003-11-26
  • 最后登录2012-11-06
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望20点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2004-06-03 16:02
不行
这个帖子不能结束

DLL没有DLLMAIN也可以使用??????

我不明白为什么?
谁接着解释
我来开帖子给分
[img]http://www.driverdevelop.com/forum/upload/walkonthesky/2004-07-08_2004-07-07_b847.gif[/img]
wei_ziyong
驱动牛犊
驱动牛犊
  • 注册日期2003-12-31
  • 最后登录2010-04-30
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望16点
  • 贡献值0点
  • 好评度16点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2004-06-03 20:45
你想不通么,是这样的啊。我个人认为好象dll是可以没有主函数的啊。你没有尝试过么?反正,我是经常这样做的了,而且程序编译连接都没有错误和警告,照洋能运行,你可一自己做一个这样的dll,运行起看嘛!

walkonthesky
驱动中牛
驱动中牛
  • 注册日期2003-11-26
  • 最后登录2012-11-06
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望20点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2004-06-04 08:57
看来我是墨守成规了!!!

见笑
[img]http://www.driverdevelop.com/forum/upload/walkonthesky/2004-07-08_2004-07-07_b847.gif[/img]
游客

返回顶部