写了一个接口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;
- }