MFC制作DLL(导出类和函数)

学了2天MFC导出DLL,发现网上描述的都不是很彻底,我这里给一个教程,希望大家能参考一次成功。
我用VC6,其他版本基本雷同。
首先,VC6新建项目,如下图流程:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
点击文件–保存工作空间,把我们的劳动成果先保存一下。
然后点文件–新建:
在这里插入图片描述
继续新建c++文件:
在这里插入图片描述
MLib.h文件内容:

#ifndef __MLIB__20200919__ // 防止重复,加上年月日,做个留念
#define __MLIB__20200919__

class MLib
{
public:
	__declspec(dllexport) static BOOL AppAlreadyRunning(const char *appKey);
	__declspec(dllexport) static CString GetAppExeDIRPath();
};

#endif

MLib.cpp内容:

#include "StdAfx.h"
#include "MLib.h"

BOOL MLib::AppAlreadyRunning(const char *appKey)
{
	// 创建互斥量
	HANDLE m_hMutex = CreateMutex(NULL, FALSE, _T(appKey));
	// 检查错误代码
	DWORD nRet = GetLastError();
	if (nRet == ERROR_ALREADY_EXISTS)
	{
		CloseHandle(m_hMutex);
		m_hMutex = NULL;
		return TRUE;
	} else {
		return FALSE;
	}
}

CString MLib::GetAppExeDIRPath()
{
	
	CString  strPathName;
	GetModuleFileName(NULL, strPathName.GetBuffer(1024), 1024);
	strPathName.ReleaseBuffer();
	int nPos  = strPathName.ReverseFind('\\');
	return strPathName.Left(nPos + 1);
}

导出类是不需要额外声明的,只要你声明一下导出类的各个方法即可,不管方法是否为静态,不信你建一个不是static的成员函数试试!关键就在于类方法前面加上__declspec(dllexport),这个方法就导出了,当然,导出函数也是一样的,比如在cpp文件里写函数后,头文件声明为:
__declspec(dllexport) void test();
你就可以导出这个函数给别的程序调用了。
编译:
在这里插入图片描述

调用DLL的方法:
新建一个MFC应用程序项目,这里我就不细说了。建好以后,建议在StdAfx.h中增加声明:

#include "../tlib/MLib.h"
#pragma comment(lib, "../tlib/Debug/Tlib.lib")

然后记得把之前编译好的Tlib.dll文件拷贝到你要调试程序的Debug目录下(或Release目录下,或你要发布应用的目录中,因为程序首先找相同目录下的dll嘛)。
调用方法就跟你把文件加入项目中一起编译时一样了,只不过你包含的头文件有__declspec(dllexport),但这并不影响include。
比如下面方法调用:

if (MLib::AppAlreadyRunning("111")) {
		AfxMessageBox("应用程序111已经运行中");
		return FALSE;
	}

	AfxMessageBox(MLib::GetAppExeDIRPath());

你可以保证程序不会重复运行,还能方便的获取当前目录,是不是包装一些常用方法到DLL动态库,更方便我们日常开发呢?

附录:引用DLL常见错误
编译DLL一般都好通过,但调用DLL的程序,我经常遇到2类错误:
1、编译阶段的链接时错误:
Linking…
111.obj : error LNK2001: unresolved external symbol “class CString __cdecl Base64Encode(unsigned char const *,unsigned int)” (?Base64Encode@@YA?AVCString@@PBEI@Z)
Debug/111.exe : fatal error LNK1120: 1 unresolved externals
这是说链接器从lib中找不到调用函数的符号,这时我们应该检查DLL库编译时是否有声明__declspec(dllexport),比如上述错误需要:__declspec(dllexport) CString Base64Encode(const unsigned char *src, size_t srclen);,当然这行声明应该写在.h文件里,然后让cpp文件引用,这里是说DLL库,不是说调用DLL的应用程序。修改后重新编译DLL,将保证lib和dll文件都被拷贝到需要的位置(我上面的列子是直接将lib设置到项目里,用父路径引用了其他项目的lib库了)。
2、运行时错误
在这里插入图片描述
这一看就知道是DLL文件没有拷贝到当前程序运行的目录下导致的。拷贝过来即可解决问题。
提一下:记得发布时应该用Release版本的dll库。

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页