本人用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;
}
可能原因有很多,比如你的函数原型(参数列表、调用约定)和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 关闭程序
}
有几个原因可以确认一下:
1、动态加载出来的函数参数个数是否正确,参数类型是否正确,在函数指针定义时就算这些错误,也可以加载成功,但是实际调用执行时会导致程序崩溃;
2、确认下动态库生成时是否有加 stdcall 的声明,如果生成时有加入该声明,在动态加载时也需要,该声明会影响出入栈的先后顺序,不一致会导致程序崩溃
Debug模式下打开call stack函数调用堆栈,找到出错的函数调用先