void CBuildImageLibDlg::OnBnClickedButtonRecog()
{
// TODO: Add your control notification handler code here
m_pThrd = AfxBeginThread(RecogFunc,this,NULL,0,0,NULL);
if( m_pThrd!= NULL)
{
m_ThreadHandle = m_pThrd->m_hThread;
//不要这么快关闭句柄,你的线程还在运行!可以在对话框的析构函数里面关闭句柄
//CloseHandle(m_ThreadHandle);
}
}
xiug修改了放在析构函数里面还是有问题
{
CBuildImageLibDlg * pDlg = (CBuildImageLibDlg *)pParam;
if (pDlg->m_vecPath.size() <= 0)
{
::MessageBox(pDlg->m_hWnd, _T("请先加载图像!"), _T("提示"), MB_OK);
return 0;;
} TCHAR szPath[MAX_PATH];
GetModuleFileName(AfxGetInstanceHandle(), szPath, MAX_PATH);
CString strDir(szPath);
strDir = strDir.Left(strDir.ReverseFind('\\')+1);
SetCurrentDirectory(strDir);
strDir += _T("TH-ImageOCR.dll");
HINSTANCE Hins = LoadLibrary(strDir);
if (Hins == NULL)
{
::MessageBox(pDlg->m_hWnd, _T("加载识别库失败!"), _T("提示"), MB_OK);
return 0;
} pInfoInit InfoInit = (pInfoInit)GetProcAddress(Hins, "WT_InfoInit");
if (InfoInit == NULL)
{
::MessageBox(pDlg->m_hWnd, _T("加载识别库失败!初始化失败!"), _T("提示"), MB_OK);
return 0;
} pExtractInfo ExtractInfo = (pExtractInfo)GetProcAddress(Hins, "WT_ExtractInfo");
if (ExtractInfo == NULL)
{
::MessageBox(pDlg->m_hWnd, _T("加载识别库失败!初始化失败!"), _T("提示"), MB_OK);
return 0;
} pExtractInfoEx ExtractInfoEx = (pExtractInfoEx)GetProcAddress(Hins, "WT_ExtractInfoEx");
if (ExtractInfoEx == NULL)
{
int err = GetLastError();
::MessageBox(pDlg->m_hWnd, _T("加载识别库失败!初始化失败!"), _T("提示"), MB_OK);
return 0;
} pInfoRelease InfoRelease = (pInfoRelease)GetProcAddress(Hins, "WT_InfoRelease");
if (InfoRelease == NULL)
{
::MessageBox(pDlg->m_hWnd, _T("加载识别库失败!初始化失败!"), _T("提示"), MB_OK);
return 0;
} pWT_GetError GetError = (pWT_GetError)GetProcAddress(Hins, "WT_GetError");
if (GetError == NULL)
{
::MessageBox(pDlg->m_hWnd, _T("加载识别库失败!初始化失败!"), _T("提示"), MB_OK);
return 0;
} pWT_SetRecogRect SetRecogRect = (pWT_SetRecogRect)GetProcAddress(Hins, "WT_SetRecogRect");
if (SetRecogRect == NULL)
{
::MessageBox(pDlg->m_hWnd, _T("加载识别库失败!初始化失败!"), _T("提示"), MB_OK);
return 0;
}
CString strPath;
pDlg->GetDlgItem(IDC_EDIT_PATH)->GetWindowText(strPath); CDC *pDC = pDlg->GetDC();
pDC->SetBkMode(TRANSPARENT); LOGFONT logfont;
memset(&logfont, 0x0, sizeof(logfont));
logfont.lfHeight = 13;
logfont.lfWeight = FW_NORMAL;
logfont.lfCharSet = GB2312_CHARSET;
wcscpy_s(logfont.lfFaceName, _T("宋体"));
CFont font;
font.CreateFontIndirect(&logfont);
CFont* poldFont = pDC->SelectObject(&font);
pDC->SetTextColor(RGB(21, 106, 161)); if (InfoInit(0x11,0x1,true))
{
pDlg->m_pShowView->GetSelectRect();
USES_CONVERSION;
for (vector<CString>::iterator iter=pDlg->m_vecPath.begin(); iter!=pDlg->m_vecPath.end(); ++iter)
{
if (!pDlg->m_pShowView->m_rcSelect.IsRectEmpty())
{
SetRecogRect(pDlg->m_pShowView->m_rcSelect.left, pDlg->m_pShowView->m_rcSelect.top, pDlg->m_pShowView->m_rcSelect.Width(), pDlg->m_pShowView->m_rcSelect.Height());
}
XTextInfo* pInfo = NULL;
CString strTemp(strPath);
strTemp += _T("\\");
strTemp += *iter; CString strOut;
strOut.Format(_T("正在识别:%s"), *iter);
pDlg->m_strStatus = strOut;
pDC->FillSolidRect(pDlg->m_rcStatus, 0xf7f7f7);
if (!pDlg->m_strStatus.IsEmpty())
{
pDC->DrawText(pDlg->m_strStatus, pDlg->m_rcStatus, DT_LEFT);
}
pInfo = ExtractInfoEx(W2A(strTemp));
int nErr = GetError();
if (pInfo == NULL && nErr != 0)
{
::MessageBox(pDlg->m_hWnd, _T("解析错误!"), _T("提示"), MB_OK);
FreeLibrary(Hins);
pDC->SelectObject(poldFont);
font.DeleteObject();
pDlg->ReleaseDC(pDC);
InfoRelease();
pDlg->GetInfoFromOutput(NULL);
return 0;
}
else if (pInfo == NULL && nErr == 0)
{
pDlg->GetInfoFromOutput(NULL);
// strTemp = strTemp.Left(strTemp.ReverseFind('.')+1) + _T("txt");
// if (!SaveInfoToTxt(strTemp))
// {
//
// //Invalidate(FALSE);
// //FreeLibrary(Hins);
// //return;
// }
}
else
{
pDlg->GetInfoFromOutput(pInfo);
// strTemp = strTemp.Left(strTemp.ReverseFind('.')+1) + _T("txt");
// if (!SaveInfoToTxt(strTemp))
// {
// //Invalidate(FALSE);
// //FreeLibrary(Hins);
// //return;
// } }
InfoRelease();
strOut.Format(_T("正在释放:%s"), *iter);
pDlg->m_strStatus = strOut;
pDC->FillSolidRect(pDlg->m_rcStatus, 0xf7f7f7);
if (!pDlg->m_strStatus.IsEmpty())
{
pDC->DrawText(pDlg->m_strStatus, pDlg->m_rcStatus, DT_LEFT);
} pDlg->m_strStatus.Empty();
pDC->FillSolidRect(pDlg->m_rcStatus, 0xf7f7f7);
}
}
else
{
::MessageBox(NULL, _T("初始化失败!"), _T("提示"), MB_OK);
FreeLibrary(Hins);
pDC->SelectObject(poldFont);
font.DeleteObject();
pDlg->ReleaseDC(pDC);
return 0;
}
pDC->SelectObject(poldFont);
font.DeleteObject();
pDlg->ReleaseDC(pDC);
::MessageBox(NULL, _T("完成!"), _T("提示"), MB_OK);
if (pDlg->m_nSelect >= 0)
{
CString strPath;
pDlg->GetDlgItem(IDC_EDIT_PATH)->GetWindowText(strPath);
strPath += _T("\\");
strPath += pDlg->m_vecPath[pDlg->m_nSelect];
if (GetFileAttributes(strPath) == 0xffffffff)
{
//m_pTextDraw->CleanStringVector();
pDlg->GetDlgItem(IDC_EDIT_RESULT)->SetWindowText(_T(""));
::MessageBox(NULL, _T("文件缺失,请重新识别并加载"), _T("提示"), MB_OK);
return 0;
}
if (pDlg->m_pShowView->m_imgShow.IsNull())
{
pDlg->m_pShowView->LoadImage(strPath);
}
else
{
pDlg->m_pShowView->m_imgShow.Destroy();
pDlg->m_pShowView->LoadImage(strPath); } if (pDlg->m_vecList.size() > pDlg->m_nSelect)
{
//m_pTextDraw->CleanStringVector();
pDlg->GetDlgItem(IDC_EDIT_RESULT)->SetWindowText(_T(""));
CString textTemp ;
vector<LineInfo> *vecInfoTemp = &pDlg->m_vecList[pDlg->m_nSelect];
for(vector<LineInfo>::iterator iter=vecInfoTemp->begin();iter!=vecInfoTemp->end();++iter)
{
if(iter==vecInfoTemp->begin())
{
textTemp = iter->strChars;
}
else
{
textTemp += _T("\r\n");
textTemp += iter->strChars;
}
}
pDlg->GetDlgItem(IDC_EDIT_RESULT)->SetWindowText(textTemp);
//m_pTextDraw->SetVectorInfo(&m_vecList[m_nSelect]);
pDlg->m_pShowView->m_vecLine = &pDlg->m_vecList[pDlg->m_nSelect];
} }
//pDlg->Invalidate(FALSE);
FreeLibrary(Hins);
return 0;
}
线程函数
线程函数创建完线程还没有退出,所以不应该这么快关闭句柄。你的这个问题应该是线程函数中调用 W2A 导致,如果m_vecPath 这个容器很大的话,W2A在频繁调用的时候会出现问题,导致的栈内存耗尽,所以保险的方式是用在频繁调用时用{}把w2a包起来,这样一退出就自动释放资源,所以你只要将 W2A 封装到一个函数里面调用,那就可以解决这个问题
2、你在主线程中调用CThreadData* pData = (CThreadData*)TlsGetValue(m_tlsIndex);
没在线程函数中看到你使用LocalAlloc分配线程局部内存,使用TlsSetValue设置内存,所以没办法判断问题所在。初步估计是TlsGetValue取到的void*内存指针在强制转换成CThreadData*后,再访问时出错,应该是你取到的不是你希望要得到的地址,再访问时就会发生越界。这种多线程的内存访问需要多加注意。