程序开发中,经常会使用到动态库,动态库不能直接运行,需要依赖其他程序调用,那么我们该如何调试我们的动态库呢?本文通过一个简单的例子说明。
使用工具:VS2008
使用语言:C++
开发步骤:
struct tDLL_INFORMATION { LPCTSTR sDLLName; LPCTSTR sFuncDescr; LPCTSTR sAuthorName; }; typedef bool (*LPFNREGISTER_CreateObject)(void**); typedef bool (*LPFNREGISTER_GetDllInformation)(void**); typedef bool (*LPFNREGISTER_ReleaseObject)(void*);
void CDllTestAppDlg::OnBnClickedBtnLoad() { CString s1 = _T(""), s=_T(""); s = _T("dll files(*.dll)|*.dll|所有文件(*.*)|*.*||"); CFileDialog de(true, s1, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR,s, NULL ); if(de.DoModal() == IDOK) { m_sDllPathName = de.GetPathName(); //path and filename } else { return; } if(m_sDllPathName.IsEmpty()) { m_btnRunDll.EnableWindow(FALSE); } else { m_btnRunDll.EnableWindow(TRUE); } CString str = _T(""); int cnt = 0,i = 0; char p[256]={0}; LPFNREGISTER_GetDllInformation lpfnRegister; HINSTANCE hInDll = NULL; hInDll = LoadLibrary(m_sDllPathName); str = _T("GetDllInformation"); cnt = str.GetLength(); for(i=0; i<cnt; i++) { p[i] = str.GetAt(i); } lpfnRegister=(LPFNREGISTER_GetDllInformation)GetProcAddress(hInDll,p); tDLL_INFORMATION* pInfo = NULL; (*lpfnRegister)((void**)&pInfo); str = pInfo->sDLLName; m_sDLLName = _T(""); cnt = str.GetLength(); for(i=0;i<cnt;i++) { m_sDLLName = m_sDLLName + str.GetAt(i); } str = pInfo->sFuncDescr; m_sFuncDescr = _T(""); cnt = str.GetLength(); for(i=0;i<cnt;i++) { m_sFuncDescr = m_sFuncDescr + str.GetAt(i); } str = pInfo->sAuthorName; m_sAuthorName = _T(""); cnt = str.GetLength(); for(i=0;i<cnt;i++) { m_sAuthorName = m_sAuthorName + str.GetAt(i); } FreeLibrary(hInDll); UpdateData(0); }效果
MyDllService.h
#pragma once #define ERR_SER_OK 0x0000 #define ERR_SER_RUN_FAILED 0x0001 #define ERR_SER_RUN_CANCEL 0x0002 #define ERR_SER_LOAD_PARAM 0x0003 class CMyDllService { public: CMyDllService(void){}; ~CMyDllService(void){}; public: virtual DWORD RunService(){return ERR_SER_RUN_FAILED;}; };调用
void CDllTestAppDlg::OnBnClickedBtnRun() { if(m_sDllPathName.IsEmpty()) { MessageBox(_T("DLL路径为空。")); return; } CMyDllService* pSer = NULL; HINSTANCE hIn = NULL; hIn = LoadLibrary(m_sDllPathName); if(hIn != INVALID_HANDLE_VALUE) {} else { CString info = _T("载入") + m_sDllPathName + _T("失败"); MessageBox(info); return; } CString str = _T(""); int cnt = 0,i = 0; char p[256]={0}; str = _T("CreateObject"); cnt = str.GetLength(); for(i=0; i<cnt; i++) { p[i] = str.GetAt(i); } LPFNREGISTER_CreateObject lpfnRegister; lpfnRegister=(LPFNREGISTER_CreateObject)GetProcAddress(hIn,p); bool result = false; if(lpfnRegister) { result =(*lpfnRegister)((void**)&(pSer)); } else { FreeLibrary(hIn); CString info = _T("载入") + m_sDllPathName + _T("失败"); MessageBox(info); return; } if(pSer && result) { DWORD dwError = 0; dwError = pSer->RunService(); } else { FreeLibrary(hIn); CString info = _T("运行") + m_sDllPathName + _T("失败"); MessageBox(info); return; } char p2[256]={0}; str = _T("ReleaseObject"); cnt = str.GetLength(); for(i=0; i<cnt; i++) { p2[i] = str.GetAt(i); } LPFNREGISTER_ReleaseObject lpfnRegister1; lpfnRegister1=(LPFNREGISTER_ReleaseObject)GetProcAddress(hIn,p2); if(lpfnRegister1) { result =(*lpfnRegister1)((void*)pSer); pSer = NULL; } FreeLibrary(hIn); }效果
1.4文件结构图
设置属性为在静态库中使用
#pragma once #include "mydllservice.h" class CMyDlgDllService : public CMyDllService { public: CMyDlgDllService(void); ~CMyDlgDllService(void); DWORD RunService(void); };
#include "StdAfx.h" #include "MyDlgDllService.h" #include "TestDlg.h" CMyDlgDllService::CMyDlgDllService(void) { } CMyDlgDllService::~CMyDlgDllService(void) { } DWORD CMyDlgDllService::RunService(void) { CTestDlg dlg; dlg.DoModal(); return ERR_SER_OK; }
struct tDLL_INFORMATION { LPCTSTR sDLLName; LPCTSTR sFuncDescr; LPCTSTR sAuthorName; }; extern "C" __declspec(dllexport) bool CreateObject(void** pObj ) { *pObj = new CMyDlgDllService; return true; } extern "C" __declspec(dllexport) bool GetDllInformation(void** pInfo) { *pInfo = new tDLL_INFORMATION; ((tDLL_INFORMATION*)(*pInfo))->sDLLName = _T("dll"); ((tDLL_INFORMATION*)(*pInfo))->sFuncDescr = _T("dll test"); ((tDLL_INFORMATION*)(*pInfo))->sAuthorName = _T("tester"); return true; } extern "C" __declspec(dllexport) bool ReleaseObject(void* pObj) { CMyDlgDllService* pTempObj = NULL; pTempObj = (CMyDlgDllService*)pObj; delete pTempObj; return true; }
原文地址:http://blog.csdn.net/bingdianlanxin/article/details/42341673