天天看點

DLL調用異常

 寫了一個接口DLL,供華為IVR平台調用實作某功能。

奇怪的事情發生了,我用自己的demo調用一切OK,用IVR平台調用出現位址錯誤。

這個問題困惑了多天,最後經人指點,改成間接調用:IVR調用DLL時,DLL調用demo,demo再調用該DLL……。

想是隻換了一個調用具體功能的父程序而已。

不知道問題出在哪,留此帖做記号。

代碼如下:

  1. // faxdll.cpp : 定義 DLL 應用程式的入口點。
  2. #include "stdafx.h"
  3. #ifdef _MANAGED
  4. #pragma managed(push, off)
  5. #endif
  6. int g_c_debug;
  7. CString csIniFile = "C://CSoft//ConfigFax.ini";
  8. TCHAR g_szFaxPath[MAX_PATH];
  9. string strOther;
  10. CRITICAL_SECTION g_cs;
  11. BOOL APIENTRY DllMain( HMODULE hModule,
  12.                        DWORD  ul_reason_for_call,
  13.                        LPVOID lpReserved
  14.                      )
  15. {
  16.     switch (ul_reason_for_call)
  17.     {
  18.     case DLL_PROCESS_ATTACH:
  19.         g_c_debug = GetPrivateProfileInt("fax","DEBUG",1,csIniFile);
  20.         GetPrivateProfileString("fax","faxdir","C://CSoft//",g_szFaxPath,MAX_PATH,csIniFile);
  21.         //disDebug("PROCESS_ATTACH");
  22.         break;
  23.     case DLL_THREAD_ATTACH:
  24.         //disDebug("THREAD_ATTACH");
  25.         break;
  26.     case DLL_THREAD_DETACH:
  27.         //disDebug("THREAD_DETACH");
  28.         break;
  29.     case DLL_PROCESS_DETACH:
  30.         //DeleteCriticalSection(&g_cs);
  31.         //disDebug("PROCESS_DETACH");
  32.         break;
  33.     default:
  34.         //disDebug("default:%d!",ul_reason_for_call);
  35.         break;
  36.     }
  37.     return TRUE;
  38. }
  39. void _stdcall disDebug(const TCHAR *szFormat, ...)
  40. {
  41.     if (g_c_debug)
  42.     {
  43.         CString  csBuffer;
  44.         TCHAR   szBuffer [4096];
  45.         SYSTEMTIME  st;   
  46.         ::GetSystemTime(&st);
  47.         va_list pArgList ;
  48.         va_start (pArgList, szFormat) ;
  49.         _vsntprintf_s (szBuffer, sizeof (szBuffer) / sizeof (TCHAR), szFormat, pArgList) ;
  50.         csBuffer.Format("%02d:%02d:%02d/t%d/t%s/r/n",st.wHour + 8,st.wMinute,st.wSecond,::GetCurrentThreadId(),szBuffer);
  51.         va_end (pArgList) ;
  52.         CString m_logErrName;
  53.         m_logErrName.Format("%s%d.log","c://Csoft//",GetCurrentThreadId());
  54.         HANDLE fh = CreateFile(m_logErrName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, 
  55.             FILE_ATTRIBUTE_NORMAL, NULL);
  56.         if(fh == INVALID_HANDLE_VALUE) 
  57.         {
  58.             return;
  59.         }
  60.         SetFilePointer(fh, 0, NULL, FILE_END);
  61.         DWORD length;
  62.         WriteFile(fh, csBuffer.GetBuffer(csBuffer.GetLength()), csBuffer.GetLength(), &length, NULL);
  63.         CloseHandle(fh);
  64.     }
  65.     return;
  66. }
  67. extern "C"
  68. {
  69.     int __stdcall CreateFaxFile(    
  70.         const char* pPhone,
  71.         const char* pCompanyName,
  72.         const char* pPhone2,
  73.         const char* pCompanyAddr,
  74.         const char* pCompanyPhone,
  75.         const char* pCompanyInfo,
  76.         char* filepath
  77.         )
  78.     {
  79.              char tiffpath[MAX_PATH];
  80.         TFAXBITMAPS faxtiff;
  81.         string sPhone = pPhone;
  82.         string sPhone2 = pPhone2;
  83.         string sCompanyName = pCompanyName;
  84.         string sCompanyAddr = pCompanyAddr;
  85.         string sCompanyPhone = pCompanyPhone;
  86.         string sCompanyInfo = pCompanyInfo;
  87.         sprintf_s(tiffpath,MAX_PATH,"%s%s.tiff",g_szFaxPath,pPhone);
  88.         //disDebug("before Createfaxfile/n");
  89.         faxtiff.CFax_BillFile(tiffpath,sPhone,sPhone2,sCompanyName,sCompanyAddr,sCompanyPhone,sCompanyInfo);
  90.         memset(filepath,0,sizeof(filepath));
  91.         strncpy(filepath,tiffpath,sizeof(tiffpath));
  92.         //disDebug("RET %s",filepath);
  93.         return 0;
  94.     }
  95.     int __stdcall DeleteFaxFile(char* pFilePath)
  96.     {
  97.         //disDebug("delete files:%s/n",pFilePath);
  98.         DWORD dwAttri = GetFileAttributes(pFilePath);
  99.         //disDebug("attribute:%x/n",dwAttri);
  100.         if (dwAttri == FILE_ATTRIBUTE_ARCHIVE)
  101.         {
  102.             //disDebug("before delete/n");
  103.             bool bdelete = DeleteFile(pFilePath);
  104.             //disDebug("after delete:%d/n",bdelete);
  105.             if(bdelete)
  106.             {
  107.                 return 0;
  108.             }
  109.         }
  110.         return 1;
  111.     }
  112. }
  113. #ifdef _MANAGED
  114. #pragma managed(pop)
  115. #endif

DEMO代碼如下:

  1. // demo.cpp : 定義控制台應用程式的入口點。
  2. //
  3. #include "stdafx.h"
  4. #include <stdlib.h>
  5. #include <windows.h>
  6. #include <string>
  7. #include <iostream>
  8. using namespace std;
  9. typedef int (__stdcall* LPFNDLLFUNC1)(char*);
  10. typedef int (__stdcall* LPFNDLLFUNC2)(const char*,const char*,const char*,const char*,const char*,const char*,char*);
  11. typedef int (__stdcall* LPFNDLLFUNC3)();
  12. HINSTANCE hDLL;  
  13. LPFNDLLFUNC1 lpfnDllFunc1;    // Function pointer
  14. LPFNDLLFUNC2 lpfnFaxFile;
  15. LPFNDLLFUNC3 lpfnTest;
  16. DWORD WINAPI ThreadFun(LPVOID n)
  17. {
  18.     TCHAR buffer[MAX_PATH];
  19.     // Handle to DLL
  20.     //lpfnTest = (LPFNDLLFUNC3)GetProcAddress(hDLL,"MyTest");
  21.     int  nReturnVal = -1;
  22.     string strPhone,strPhone2,strCompanyInfo,strCompanyName,strCompanyAddr,strCompanyPhone;
  23.     memset(buffer,0,sizeof(buffer));
  24.     itoa(GetCurrentThreadId(),buffer,10);
  25. //  nReturnVal = lpfnDllFunc1("C://CSoft//20080920_DEBUG.log");
  26. //  while(1)
  27.     {
  28. //      nReturnVal = lpfnTest();
  29. //      printf("ID:%d,nret:%d/n",GetCurrentThreadId(),nReturnVal);
  30. //      return 0;
  31.     }
  32.     //cout<<"dll檔案目前目錄"<<"/t"<<buffer<<endl;
  33.     //cout << "來電号碼,查詢号碼,公司名稱,公司位址,公司電話,,公司簡介"<<endl;
  34.     printf("ID:%d,nret:%s/n",GetCurrentThreadId(),"before");
  35.     strPhone = itoa(GetCurrentThreadId(),buffer,10);
  36.     nReturnVal = lpfnFaxFile(strPhone.c_str(),strCompanyName.c_str(),strPhone2.c_str(),strCompanyAddr.c_str(),strCompanyPhone.c_str(),strCompanyInfo.c_str(),buffer);
  37.     printf("ID:%d,nret:%d/n",GetCurrentThreadId(),nReturnVal);
  38.     //cout << "傳回值 "<<nReturnVal <<"thread:"<< GetCurrentThreadId() << endl;
  39.     //cout <<buffer<<endl;
  40.     return 0;
  41. }
  42. int _tmain(int argc, _TCHAR* argv[])
  43. {
  44.     const int nTheadNum = 2;
  45.     HANDLE harg[nTheadNum];
  46.     hDLL = ::LoadLibrary("faxdll.dll");
  47.     if (hDLL != NULL)
  48.     {
  49.         lpfnDllFunc1 = (LPFNDLLFUNC1)GetProcAddress(hDLL,"DeleteFaxFile");
  50.         lpfnFaxFile = (LPFNDLLFUNC2)GetProcAddress(hDLL,"CreateFaxFile");
  51.         lpfnTest = (LPFNDLLFUNC3)GetProcAddress(hDLL,"MyTest");
  52.         if (!lpfnDllFunc1)
  53.         {
  54.             // handle the error
  55.             printf("入口裝載失敗/n");
  56.             FreeLibrary(hDLL);       
  57.             return 1;
  58.         }
  59.         else
  60.         {
  61.             // call the function
  62.             for (int i=0; i< nTheadNum; ++i)
  63.             {
  64.                 //ThreadFun(0);
  65.                 //Sleep(50);
  66.                 if((harg[i] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFun,0,0,NULL)) == NULL)
  67.                     cout << "線程建立失敗" << endl;
  68.             }
  69.         }
  70.     }
  71.     else
  72.     {
  73.         printf("裝載失敗!/n");
  74.         DWORD derr = GetLastError();
  75.         printf("%x/n",derr);
  76.     }
  77.     DWORD dw = WaitForMultipleObjects(nTheadNum,harg,true,4000);
  78.     Sleep(100);
  79.     if(dw == WAIT_TIMEOUT)//INFINITE
  80.     {
  81.         for (int i = 0; i < nTheadNum; ++i)
  82.         {
  83.             TerminateThread(harg[i],1);
  84.         }
  85.         cout <<"/n/n逾時退出/n/n"<<endl;
  86.     }
  87.     cout <<"/n/n/n退出碼:"<<dw<<endl;
  88.     FreeLibrary(hDLL);
  89.     system("pause");
  90.     return 0;
  91. }

繼續閱讀