寫了一個接口DLL,供華為IVR平台調用實作某功能。
奇怪的事情發生了,我用自己的demo調用一切OK,用IVR平台調用出現位址錯誤。
這個問題困惑了多天,最後經人指點,改成間接調用:IVR調用DLL時,DLL調用demo,demo再調用該DLL……。
想是隻換了一個調用具體功能的父程序而已。
不知道問題出在哪,留此帖做記号。
代碼如下:
- // faxdll.cpp : 定義 DLL 應用程式的入口點。
- #include "stdafx.h"
- #ifdef _MANAGED
- #pragma managed(push, off)
- #endif
- int g_c_debug;
- CString csIniFile = "C://CSoft//ConfigFax.ini";
- TCHAR g_szFaxPath[MAX_PATH];
- string strOther;
- CRITICAL_SECTION g_cs;
- BOOL APIENTRY DllMain( HMODULE hModule,
- DWORD ul_reason_for_call,
- LPVOID lpReserved
- )
- {
- switch (ul_reason_for_call)
- {
- case DLL_PROCESS_ATTACH:
- g_c_debug = GetPrivateProfileInt("fax","DEBUG",1,csIniFile);
- GetPrivateProfileString("fax","faxdir","C://CSoft//",g_szFaxPath,MAX_PATH,csIniFile);
- //disDebug("PROCESS_ATTACH");
- break;
- case DLL_THREAD_ATTACH:
- //disDebug("THREAD_ATTACH");
- break;
- case DLL_THREAD_DETACH:
- //disDebug("THREAD_DETACH");
- break;
- case DLL_PROCESS_DETACH:
- //DeleteCriticalSection(&g_cs);
- //disDebug("PROCESS_DETACH");
- break;
- default:
- //disDebug("default:%d!",ul_reason_for_call);
- break;
- }
- return TRUE;
- }
- void _stdcall disDebug(const TCHAR *szFormat, ...)
- {
- if (g_c_debug)
- {
- CString csBuffer;
- TCHAR szBuffer [4096];
- SYSTEMTIME st;
- ::GetSystemTime(&st);
- va_list pArgList ;
- va_start (pArgList, szFormat) ;
- _vsntprintf_s (szBuffer, sizeof (szBuffer) / sizeof (TCHAR), szFormat, pArgList) ;
- csBuffer.Format("%02d:%02d:%02d/t%d/t%s/r/n",st.wHour + 8,st.wMinute,st.wSecond,::GetCurrentThreadId(),szBuffer);
- va_end (pArgList) ;
- CString m_logErrName;
- m_logErrName.Format("%s%d.log","c://Csoft//",GetCurrentThreadId());
- HANDLE fh = CreateFile(m_logErrName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_ALWAYS,
- FILE_ATTRIBUTE_NORMAL, NULL);
- if(fh == INVALID_HANDLE_VALUE)
- {
- return;
- }
- SetFilePointer(fh, 0, NULL, FILE_END);
- DWORD length;
- WriteFile(fh, csBuffer.GetBuffer(csBuffer.GetLength()), csBuffer.GetLength(), &length, NULL);
- CloseHandle(fh);
- }
- return;
- }
- extern "C"
- {
- int __stdcall CreateFaxFile(
- const char* pPhone,
- const char* pCompanyName,
- const char* pPhone2,
- const char* pCompanyAddr,
- const char* pCompanyPhone,
- const char* pCompanyInfo,
- char* filepath
- )
- {
- char tiffpath[MAX_PATH];
- TFAXBITMAPS faxtiff;
- string sPhone = pPhone;
- string sPhone2 = pPhone2;
- string sCompanyName = pCompanyName;
- string sCompanyAddr = pCompanyAddr;
- string sCompanyPhone = pCompanyPhone;
- string sCompanyInfo = pCompanyInfo;
- sprintf_s(tiffpath,MAX_PATH,"%s%s.tiff",g_szFaxPath,pPhone);
- //disDebug("before Createfaxfile/n");
- faxtiff.CFax_BillFile(tiffpath,sPhone,sPhone2,sCompanyName,sCompanyAddr,sCompanyPhone,sCompanyInfo);
- memset(filepath,0,sizeof(filepath));
- strncpy(filepath,tiffpath,sizeof(tiffpath));
- //disDebug("RET %s",filepath);
- return 0;
- }
- int __stdcall DeleteFaxFile(char* pFilePath)
- {
- //disDebug("delete files:%s/n",pFilePath);
- DWORD dwAttri = GetFileAttributes(pFilePath);
- //disDebug("attribute:%x/n",dwAttri);
- if (dwAttri == FILE_ATTRIBUTE_ARCHIVE)
- {
- //disDebug("before delete/n");
- bool bdelete = DeleteFile(pFilePath);
- //disDebug("after delete:%d/n",bdelete);
- if(bdelete)
- {
- return 0;
- }
- }
- return 1;
- }
- }
- #ifdef _MANAGED
- #pragma managed(pop)
- #endif
DEMO代碼如下:
- // demo.cpp : 定義控制台應用程式的入口點。
- //
- #include "stdafx.h"
- #include <stdlib.h>
- #include <windows.h>
- #include <string>
- #include <iostream>
- using namespace std;
- typedef int (__stdcall* LPFNDLLFUNC1)(char*);
- typedef int (__stdcall* LPFNDLLFUNC2)(const char*,const char*,const char*,const char*,const char*,const char*,char*);
- typedef int (__stdcall* LPFNDLLFUNC3)();
- HINSTANCE hDLL;
- LPFNDLLFUNC1 lpfnDllFunc1; // Function pointer
- LPFNDLLFUNC2 lpfnFaxFile;
- LPFNDLLFUNC3 lpfnTest;
- DWORD WINAPI ThreadFun(LPVOID n)
- {
- TCHAR buffer[MAX_PATH];
- // Handle to DLL
- //lpfnTest = (LPFNDLLFUNC3)GetProcAddress(hDLL,"MyTest");
- int nReturnVal = -1;
- string strPhone,strPhone2,strCompanyInfo,strCompanyName,strCompanyAddr,strCompanyPhone;
- memset(buffer,0,sizeof(buffer));
- itoa(GetCurrentThreadId(),buffer,10);
- // nReturnVal = lpfnDllFunc1("C://CSoft//20080920_DEBUG.log");
- // while(1)
- {
- // nReturnVal = lpfnTest();
- // printf("ID:%d,nret:%d/n",GetCurrentThreadId(),nReturnVal);
- // return 0;
- }
- //cout<<"dll檔案目前目錄"<<"/t"<<buffer<<endl;
- //cout << "來電号碼,查詢号碼,公司名稱,公司位址,公司電話,,公司簡介"<<endl;
- printf("ID:%d,nret:%s/n",GetCurrentThreadId(),"before");
- strPhone = itoa(GetCurrentThreadId(),buffer,10);
- nReturnVal = lpfnFaxFile(strPhone.c_str(),strCompanyName.c_str(),strPhone2.c_str(),strCompanyAddr.c_str(),strCompanyPhone.c_str(),strCompanyInfo.c_str(),buffer);
- printf("ID:%d,nret:%d/n",GetCurrentThreadId(),nReturnVal);
- //cout << "傳回值 "<<nReturnVal <<"thread:"<< GetCurrentThreadId() << endl;
- //cout <<buffer<<endl;
- return 0;
- }
- int _tmain(int argc, _TCHAR* argv[])
- {
- const int nTheadNum = 2;
- HANDLE harg[nTheadNum];
- hDLL = ::LoadLibrary("faxdll.dll");
- if (hDLL != NULL)
- {
- lpfnDllFunc1 = (LPFNDLLFUNC1)GetProcAddress(hDLL,"DeleteFaxFile");
- lpfnFaxFile = (LPFNDLLFUNC2)GetProcAddress(hDLL,"CreateFaxFile");
- lpfnTest = (LPFNDLLFUNC3)GetProcAddress(hDLL,"MyTest");
- if (!lpfnDllFunc1)
- {
- // handle the error
- printf("入口裝載失敗/n");
- FreeLibrary(hDLL);
- return 1;
- }
- else
- {
- // call the function
- for (int i=0; i< nTheadNum; ++i)
- {
- //ThreadFun(0);
- //Sleep(50);
- if((harg[i] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFun,0,0,NULL)) == NULL)
- cout << "線程建立失敗" << endl;
- }
- }
- }
- else
- {
- printf("裝載失敗!/n");
- DWORD derr = GetLastError();
- printf("%x/n",derr);
- }
- DWORD dw = WaitForMultipleObjects(nTheadNum,harg,true,4000);
- Sleep(100);
- if(dw == WAIT_TIMEOUT)//INFINITE
- {
- for (int i = 0; i < nTheadNum; ++i)
- {
- TerminateThread(harg[i],1);
- }
- cout <<"/n/n逾時退出/n/n"<<endl;
- }
- cout <<"/n/n/n退出碼:"<<dw<<endl;
- FreeLibrary(hDLL);
- system("pause");
- return 0;
- }