MyApp(A.exe)调用了MyDLL(B.dll),由于B.h、B.lib和B.dll是已知的,所以在MyApp中,我直接把B.lib填在了Settings-->Link中;
MyDLL B.dll又调用了C.dll(第三方库),我用函数指针引出C.dll中的导出函数。
问题是,当我在MyDLL的构造函数中执行LoadLibrary("C.dll")(C.dll及其相关dll都在C:\WINDOWS\system32目录下)时,返回的HANDLE为NULL,调用GetLastError显示错误代码为998。
请问这是怎么回事,如何解决?
我在网上找了很多,有的说指针错误或者结构体未初始化,但我这是在构造函数中调用的,应该在其它动作执行之前的事了。
这问题,搞了好久,搞不定!着急啊!

解决方案 »

  1.   

    楼主2点多还在努力,真辛苦啊。
    一般LoadLibrary不太可能出现998的问题。如果你在LoadLibrary失败后直接调用GetLastError,返回998。那估计你准备Load的这个DLL在他的初始化或者DllMain中有什么代码造成了998的错误。而不是你的代码有问题。如果这个C.dll也是你负责的,可能需要检查下这个C.dll了。如果C.dll没法查看源代码或者调试。那可能不能这么直接Load这个C.dll。
    具体问题还是在这个C.dll上。
      

  2.   

    http://support.microsoft.com/kb/196069
    微软这里有篇文章
    症状
    LoadLibrary() API 有时会遇到试图映射到调用进程地址空间指定模块时发生访问冲突。 在此事件, LoadLibrary() 返回值为 NULL 并且 GetLastError() 返回错误代码是 998 (ERROR_NOACCESS)。回到顶端
    原因
    WindowsNT 状态代码 STATUS _ ACCESS _ VIOLATION 映射到 ERROR_NOACCESS Win 32 错误代码。 因此, 如果操作系统加载程序遇到访问冲突 (异常 C 0000005) 映射指定 DLL 时图像文件或执行启动代码, 加载将设置到 998 (ERROR_NOACCESS) 最后错误并 LoadLibrary() 函数将失败, 返回值为 NULL。回到顶端
    更多信息
    当启动代码, 中任意位置发生访问冲突异常发送器检测是否正在调试进程遇到此异常。 若是, 此第一次机会异常发送到调试器。为解决 LoadLibrary() 故障, 运行应用程序在调试器并启用首次机会异常处理为 C 0000005 访问冲突异常。如果调用 LoadLibrary() 函数, 时发生访问冲突应用程序将中断到调试器。 调试程序调用堆栈然后跟踪用于发生异常。堆栈跟踪可帮助您缩小实际问题与正在遇到异常。请有关如何启用首次机会异常处理为 C 0000005 访问冲突异常, 请参考其调试器文档。 
      

  3.   

    具体的调试方法:
    in the visual c++ IDE, to enable catching of first chance exceptions, you would start your applciation, breakpoint using f-9 somewhere before you call the LoadLibrary() select Debug->Exceptions and change access violation to stop always, debug->go your code (f-5) and when the exception occurs (if this is indeed the issue which it sounds like it is) look at the call stack, and start debugging what happened.
      

  4.   

    把dll放到debug下试试是否还有问题
      

  5.   

    多谢各位!
    C.dll的确可以用上述方法Load,我们以前的工程实现过;
    Debug和Release都不行,不过在我尝试的一台电脑上居然Release可以而Debug不可以;
    C 0000005 ,出现过这个地址访问异常,但微软这一段说得太模糊了(我查到说这段话是由软件自动翻译的,不好理解),谁能详细解释下?
    谢谢了!
      

  6.   

    按照你的描述你的app工程已经将c.dll映像那么试验一下GetModuleHandle看是否能得到C.dll的HANDLE
      

  7.   

    你试一下另做一个测试项目,用LoadLibrary加载c.dll,看是否正常。有些dll不能加载太早,只能在运行中动态加载。
      

  8.   

    这个问题用以下方法解决了:
    在MyDll工程中添加一个导出函数func,在func的函数体中LoadLibrary("C.dll"),然后在MyApp中调用func即可。
    为什么这样可以实现?是否跟执行先后顺序有关?
      

  9.   

    这就是我在10楼所说的,有些dll不能加载太早,可以认为与dll加载的先后次序有关。C.dll就属于这类,具体出错的原因有很多种可能,从这个错误码来看,可能是dll访问了还没有分配的内存地址,该内存地址要等其它的某个dll加载后才有效。