FreeLibrary释放加载的dll时检测到c0000374的严重错误

时间:2017-07-08 11:49:54

标签: c++ c visual-studio dll

当我尝试释放用户定义的DLL时,我遇到了内存错误。如果您不想知道此问题的背景,我建议您从第2节开头阅读我的问题。用户定义的DLL

背景

在我的程序中,我需要使用第三方库。 在以下部分中,我将其称为LIB-A / DLL-A 。可以使用4个函数描述该库的抽象过程:

initResources(): initialze the configuration.
callAPI_to_saveAsFile(...): main process.
freeMem(...): free memory of returned data.
destroyResources(): free memory of the configuration.

已使用的LIB-A引用了ice34d.dlliceutil34d.dll。通过在我的项目(我将此程序称为exe-A中添加lib和包含的文件,我发现这些功能可以正常运行。

但现在我必须使用另一种方法来引用DLL-A。换句话说,我必须使用LoadLibraryGetProcAddressFreeLibrary来完成此任务。由于我发现DLL-A没有提供上述功能的任何可用界面,因此我尝试从包含DLL-A的文件夹中删除exe-A。结果显示 DLL-A不是有效文件exe-A可以在没有它的情况下正常运行。

用户定义的DLL

由于DLL-A无效,我必须编写一个用户定义的DLL来包装上述4个函数,我将此程序称为DLL-B DLL-B已与此类libs链接:

iced.lib
iceutild.lib
LIB-A

虽然DLL-A无效,但LIB-A是必要的,因为我推断上述4个功能不仅已声明,而且还在LIB-A中定义,DLL-A实际上是#include "LIBA.h" #ifdef MYLIBDLL #define CM_EXTERN extern "C" _declspec(dllimport) #else #define CM_EXTERN extern "C" _declspec(dllexport) #endif CM_EXTERN int w_initResources(); CM_EXTERN int w_callAPI_to_saveAsFile(...); CM_EXTERN int w_destroyResources(); CM_EXTERN int w_freeMem(...); 空。在设置了libs和包含的文件之后,我编写了4个包装函数。以下是.h文件和.cpp文件的主要部分。

.h文件:(省略一些参数)

#include "stdafx.h"
#pragma comment (lib, "../music-lib/release_dll/iced.lib") 
#pragma comment (lib, "../music-lib/release_dll/iceutild.lib") 
#pragma comment (lib, "../music-lib/release_dll/DLLA.lib") 

int w_initResources(){
    return initResources();
}

int w_destroyResources(){
    return destroyResources();
}

int w_freeMem(...){
    return freeMem(...);
}

int w_callAPI_to_saveAsFile(...){
    return callAPI_to_saveAsFile(...);
}

char* w_callAPI_to_downFileByte(char* fileURL,char *ret_bytes){
    return callAPI_to_downFileByte(fileURL, ret_bytes);
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

.cpp文件:

exe-B

问题

毕竟,我开始编写一个测试程序(我称之为DLL-B。在此程序中,我使用此类代码加载typedef int (*callAPI_to_saveAsFile_ptr)(...); typedef int (*initResources_ptr)(); typedef int (*destroyResources_ptr)(); typedef int (*freeMem_ptr)(...);

.h文件:

callAPI_to_saveAsFile_ptr Proc_API = NULL;
initResources_ptr init_API = NULL;
destroyResources_ptr destru_API = NULL;
freeMem_ptr free_API = NULL;

HINSTANCE h = LoadLibraryA("DLLB.dll");
cout << "ERROR:" << GetLastError() << endl;
if (h){
    Proc_API = (callAPI_to_saveAsFile_ptr)GetProcAddress(h, "w_callAPI_to_saveAsFile");
    init_API = (initResources_ptr)GetProcAddress(h, "w_initResources");
    destru_API = (destroyResources_ptr)GetProcAddress(h, "w_destroyResources");
    free_API = (freeMem_ptr)GetProcAddress(h, "w_freeMem");
    cout << "Have loaded: " << "DLLB.dll" << " successfully!" << endl;
}
else{
    cout << "Do not find this DLL:" << "DLLB.dll" << endl;
    FreeLibrary(h);
    return 0x100;
}
int errorflag=0;
if (Proc_API==NULL){
    cout << "Function not loaded: callAPI_to_saveAsFile" << endl;
    errorflag = errorflag | 0x001;
}
if (init_API==NULL){
    cout << "Function not loaded: initResources" << endl;
    errorflag = errorflag | 0x002;
}
if (destru_API==NULL){
    cout << "Function not loaded: destroyResources" << endl;
    errorflag = errorflag | 0x004;
}
if (CMISS_free_API==NULL){
    cout << "Function not loaded: freeMem" << endl;
    errorflag = errorflag | 0x008;
}
if (errorflag!=0){
    FreeLibrary(h);
    return 0x100 | errorflag;
}
cout << "Function loaded successfully!" << endl;
...Perform above functions...
if(h)
    FreeLibrary(h);
    return 0;

.cpp文件:

Critical error detected c0000374
exeB.exe has triggered a breakpoint.

令人困惑的是,即使程序编译得很好,GetLastError()也会返回0,并且所有4个功能都能很好地执行。但是,一旦我让程序释放DLL实例,我就会收到这样的错误:

DLL-C

如果我没有释放库,则此程序中不会出现错误。

为了证明我的猜测,我又做了两次实验:

EXP1

我编写了一个DLL(LIB-D)来包装我自己设计的另一个库(DLL-C)。我在本节中通过类似的方法加载DLL-C。问题。结果显示ice可以无错误地释放。 DLL-C和DLL-B之间的唯一区别是DLL-B加载第三方库(LIB-ALIB-D),DLL-C加载一个简单的库(HINSTANCE h = LoadLibraryA("DLLB.dll"); cout << "ERROR:" << GetLastError() << endl; if (h){ cout << "H_Valid!" << endl; FreeLibrary(h); cout << "Have loaded: " << "DLLB.dll" << " successfully and free it!" << endl; return 0; } else{ cout << "Do not find this DLL:" << "DLLB.dll" << endl; FreeLibrary(h); return 0x100; } )由我自己设计。似乎这个错误是由第三方库触发的。不幸的是,我看不到这些外部库的细节。

EXP2

我按如下方式更改.cpp文件:

DLL-B

令人震惊的是,虽然我对加载的Critical error detected c0000374 exeB.exe has triggered a breakpoint. 什么都不做,但是一旦我加载它,我就无法安全地释放它。该错误与上面的错误相同。问题

$.ajax({
        url: "<?php echo url('master/add-car-to-db');?>", 
        method : "post",

        data :  completeData ,
        success : function (data){
                    data=parse.JSON(data);
            if(data.success == 1){
                            window.location="<?php echo url('master/add-car-view');?>";

                        }
        },
        error:  function(data,status){
            alert(JSON.stringify(data));
        }
    });

我怎么能解决这个问题?这是否意味着我无法释放图书馆但是正常使用它?

0 个答案:

没有答案