首页 > 代码库 > VS之动态库调试

VS之动态库调试

程序开发中,经常会使用到动态库,动态库不能直接运行,需要依赖其他程序调用,那么我们该如何调试我们的动态库呢?本文通过一个简单的例子说明。

使用工具:VS2008

使用语言:C++

开发步骤:

1.调用动态库的应用程序

1.1新建对话框应用程序

技术分享

1.2设计动态库接口

该接口用于在加载动态库时显示动态库的一些基本信息
DllTestAppDlg.h
struct tDLL_INFORMATION
{
	LPCTSTR	sDLLName;
	LPCTSTR	sFuncDescr;
	LPCTSTR	sAuthorName;
};

typedef bool (*LPFNREGISTER_CreateObject)(void**);
typedef bool (*LPFNREGISTER_GetDllInformation)(void**);
typedef bool (*LPFNREGISTER_ReleaseObject)(void*);
DllTestAppDlg.cpp
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);
}
效果
技术分享

1.3设计调用接口类

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文件结构图

技术分享 技术分享

2.对话框动态库

2.1新建对话框动态库

设置属性为在静态库中使用

技术分享

2.2添加接口类

技术分享

2.3从接口类派生自己的类并重新虚函数

MyDlgDllService.h
#pragma once
#include "mydllservice.h"

class CMyDlgDllService : public CMyDllService
{
public:
	CMyDlgDllService(void);
	~CMyDlgDllService(void);
	DWORD RunService(void);
};
MyDlgDllService.cpp
#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;
}

2.4设计动态库接口

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;
}

2.5文件结构图

技术分享 技术分享

源码下载



VS之动态库调试