调用DLL中函数时出现异常,求大神指教! 20C

本人用vs2010根据网上教程编写了一个调用DLL的小程序,但是出现了0x00a163b8 处有未经处理的异常: 0xC0000005: Access violation的异常。调试模式的位置是 mainret = main(argc, argv, envp);请各位指出问题所在。代码如下:
#include
#include

using namespace std;

int main(){
typedef int (*OpenComPort)(int,unsigned char *,unsigned char,int *);
typedef int (*GetReaderInformation)(unsigned char *, unsigned char *, unsigned char *, unsigned char *,unsigned char *, unsigned char *, unsigned char *,unsigned char *, int);
typedef int (*SetWorkMode)(unsigned char *, unsigned char * , int );
typedef int (*SetRelay)(unsigned char *,unsigned char *, unsigned char *,int );
typedef int (*Inventory_G2)(unsigned char *, unsigned char , unsigned char , unsigned char , unsigned char ,unsigned char ,unsigned char *, int * , int *,int);
typedef int (*CloseComPort)(void);
typedef int (*CloseSpecComPort)(int);
int Port = 3;
unsigned char ComAdr = 0xFF;
unsigned char Baud = 5;//对应的波特率见说明文件
int handle = 0;
unsigned char VersionInfo[2] = {0,0};
unsigned char ReaderType = 0;
unsigned char TrType = 0;
unsigned char dmaxfre = 0;
unsigned char dminfre = 0;
unsigned char powerdBm = 0;
unsigned char ScanTime = 0;
unsigned char Parameter[6] = {0x01,0x0a,0x04,0x00,0x10,0x00};
unsigned char Qvalue = 0;
unsigned char Session = 0;
unsigned char AdrTID = 0x00;
unsigned char LenTID = 0x03;
unsigned char TIDFlag = 1;
unsigned char EPClenandEPC[1000];
int Totallen = 0,CardNum = 0;

HMODULE hDLL = LoadLibrary("UHFReader188.dll"); //加载dll文件 
if(hDLL != NULL){  
    OpenComPort fp1 = OpenComPort(GetProcAddress(hDLL,"OpenComPort")); //得到dll中的第一个函数
    GetReaderInformation fp2 = GetReaderInformation(GetProcAddress(hDLL,"GetReaderInformation")); 
    SetWorkMode fp3 = SetWorkMode(GetProcAddress(hDLL,"SetWorkMode")); 
    SetRelay fp4 = SetRelay(GetProcAddress(hDLL,"SetRelay")); 
    Inventory_G2 fp5 = Inventory_G2(GetProcAddress(hDLL,"Inventory_G2")); 
    CloseComPort fp6 = CloseComPort(GetProcAddress(hDLL,"CloseComPort")); 
    if(fp1 != NULL){
        cout << "it can run the dll." << endl;
        int a = fp1(Port,&ComAdr,Baud,&handle); 
        cout << a << " " << handle << endl;
        cout << int(ComAdr) << endl;
    }  
    else{  
        cout<<"Cannot Find Function "<<"OpenComPort"<<endl;  
    } 
    //ComAdr = 0xFF;
    if (fp2 != NULL){
        cout << "it can run the function2 of dll." <<endl;
        cout << fp2(&ComAdr,VersionInfo,&ReaderType,&TrType,&dmaxfre,&dminfre,&powerdBm,&ScanTime,handle) << endl; //代码执行到此处,出现异常。
        cout  << handle << endl;
        cout << int(ComAdr) <<endl;
    }
    else{  
        cout<<"Cannot Find Function2 "<<"GetReaderInformation"<<endl;  
    }
    if (fp3 != NULL){
        cout << "it can run the function3 of dll." <<endl;
        cout << fp3(&ComAdr,Parameter,handle) <<endl; 
    }
    else{  
        cout << "Cannot Find Function3 " << "SetWorkMode" << endl;  
    } 
    if (fp4 != NULL){
        cout << "it can run the function4 of dll." << endl;
        cout << fp4(&ComAdr,&Qvalue,&Session,handle) << endl; 
    }
    else{  
        cout<<"Cannot Find Function4 "<<"SetRelay"<<endl;  
    } 
    if (fp5 != NULL){
        cout << "it can run the function5 of dll." <<endl;
        cout << fp5(&ComAdr,Qvalue,Session,AdrTID,LenTID,TIDFlag,EPClenandEPC,&Totallen,&CardNum,handle) << endl; 
        cout << "all is ok!!" <<endl;
    }
    else{  
        cout<<"Cannot Find Function5"<<"Inventory_G2"<<endl;  
    }
    if (fp6 != NULL){
        cout << "it can run the function6 of dll." <<endl;
        cout << fp6() <<endl; 
    }
    else{  
        cout<<"Cannot Find Function6"<<"CloseComPort"<<endl;  
    } 
}  
else{  
    std::cout<<"Cannot Find "<<"dll"<<std::endl;  
}
FreeLibrary(hDLL);
return 1;  

}

5个回答

可能原因有很多,比如你的函数原型(参数列表、调用约定)和dll里函数的不一致
或者你分配内存有问题,比如dll要修改一个指针,你传了常量
再可能dll本身丢出了异常,比如说你这个是一个阅读器吧,你的硬件本身没工作,或者dll有bug
你最好先拿厂家的程序调试,然后再整合到你的程序里。

个人觉得最有可能是DLL需要的指针与你给的指针不匹配造成。
比如说VersionInfo,DLL内部是如此赋值 :strcpy(VersionInfo, "AA").
而你给定的空间只有两个字节,所以此操作破坏了后续的变量空间,造成异常。

LONG WINAPI MyUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *pExceptionPointers)
{

SetErrorMode( SEM_NOGPFAULTERRORBOX );

//收集信息
CString strBuild;
strBuild.Format(_T("Build: %s %s"), __DATE__, __TIME__);
CString strError;
HMODULE hModule;
TCHAR szModuleName[MAX_PATH] = _T("");
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)pExceptionPointers->ExceptionRecord->ExceptionAddress, &hModule);
GetModuleFileName(hModule, szModuleName, ARRAYSIZE(szModuleName));
strError.AppendFormat(_T("%s %d , %d ,%d."), szModuleName,pExceptionPointers->ExceptionRecord->ExceptionCode, pExceptionPointers->ExceptionRecord->ExceptionFlags, pExceptionPointers->ExceptionRecord->ExceptionAddress);

//生成 mini crash dump
BOOL bMiniDumpSuccessful;

// TCHAR szPath[MAX_PATH];
TCHAR szFileName[MAX_PATH];
TCHAR* szAppName = _T("OCTOPUS");
TCHAR* szVersion = _T("v1.0");
DWORD dwBufferSize = MAX_PATH;
HANDLE hDumpFile;
SYSTEMTIME stLocalTime;
MINIDUMP_EXCEPTION_INFORMATION ExpParam;
GetLocalTime( &stLocalTime );
CString cstrName = GetAppPath();

memset(szFileName,0,MAX_PATH);

TCHAR abPath[MAX_PATH]; 
memset(abPath,0,MAX_PATH);
memcpy(abPath,cstrName.GetBuffer(),cstrName.GetLength());

//     StringCchPrintfA( szFileName, MAX_PATH, _T("%s%s"), cstrName.GetBuffer(), szAppName );
//     CreateDirectory( szFileName, NULL );
StringCchPrintfA( szFileName, MAX_PATH, _T("%04d%02d%02d-%02d%02d%02d-%ld-%ld_%s.dmp"),  
    stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay, 
    stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond, 
    GetCurrentProcessId(), GetCurrentThreadId(),OCTOPUS_VERSION_NUM);

strcat(abPath,szFileName);

hDumpFile = CreateFile(abPath, GENERIC_READ|GENERIC_WRITE, 
    FILE_SHARE_WRITE|FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);

// MINIDUMP_USER_STREAM UserStream[2];
// MINIDUMP_USER_STREAM_INFORMATION UserInfo;
// UserInfo.UserStreamCount = 1;
// UserInfo.UserStreamArray = UserStream;
// UserStream[0].Type = CommentStreamA;
// UserStream[0].BufferSize = strBuild.GetLength()*sizeof(TCHAR);
// UserStream[0].Buffer = strBuild.GetBuffer();
// UserStream[1].Type = CommentStreamA;
// UserStream[1].BufferSize = strError.GetLength()*sizeof(TCHAR);
// UserStream[1].Buffer = strError.GetBuffer();

ExpParam.ThreadId = GetCurrentThreadId();
ExpParam.ExceptionPointers = pExceptionPointers;
ExpParam.ClientPointers = TRUE;

//     MINIDUMP_TYPE MiniDumpWithDataSegs = MiniDumpNormal 
//         | MiniDumpWithUnloadedModules 
//         | MiniDumpWithIndirectlyReferencedMemory 
//         | MiniDumpScanMemory 
//         | MiniDumpWithProcessThreadData 
//         | MiniDumpWithThreadInfo;

bMiniDumpSuccessful = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), 
    hDumpFile, MiniDumpNormal/*MiniDumpWithPrivateReadWriteMemory*/, &ExpParam, NULL, NULL);

if(TRUE == bMiniDumpSuccessful)
{
    //AfxMessageBox(_T("Please send dmp file to the developers!\n They will deal with the trouble!"));
    if(IDOK==MessageBox(NULL,_T("Confirm to send the crash information to the developer for improvement?"),_T("Er...,Octopus crashed!"),MB_OKCANCEL))
    {
        char cUserName[255];
        char errInfo[256];
        memset(cUserName,0,sizeof(cUserName));
        memset(errInfo,0,sizeof(errInfo));

        DWORD dwcbBuffer = 255;
        GetUserName(cUserName,&dwcbBuffer);
        sprintf_s(errInfo,"%s%s","this dmp file is sent off by user:",cUserName);

        char* attachFiles[2];
        attachFiles[0]=(char*)malloc(sizeof(char)*256);
        attachFiles[1]=(char*)malloc(sizeof(char)*256);

        memset(attachFiles[0],0,256);
        memset(attachFiles[1],0,256);

        strcpy(attachFiles[0],abPath);

        int res=sendmail(errInfo,attachFiles,1);
        if(0 == res)
        {
            AfxMessageBox(_T("Send dmp File Successfully!"));
        }
        else
        {
            AfxMessageBox(_T("Send dmp File Failed!"));
        }
    }
}
else
{
    int id;
    id = GetLastError();
    CString cstrId;
    cstrId.Format(_T("dmp File Create Failed!Please check your memory!ID:%d"),id);
    AfxMessageBox(cstrId);
}

exit(0);

return EXCEPTION_EXECUTE_HANDLER/*EXCEPTION_CONTINUE_SEARCH*/; //或者 EXCEPTION_EXECUTE_HANDLER 关闭程序

}

sinat_34587025
长师两刃刀 什么意思,没有看懂?
一年多之前 回复

有几个原因可以确认一下:
1、动态加载出来的函数参数个数是否正确,参数类型是否正确,在函数指针定义时就算这些错误,也可以加载成功,但是实际调用执行时会导致程序崩溃;
2、确认下动态库生成时是否有加 stdcall 的声明,如果生成时有加入该声明,在动态加载时也需要,该声明会影响出入栈的先后顺序,不一致会导致程序崩溃

Debug模式下打开call stack函数调用堆栈,找到出错的函数调用先

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问