在MFC中调用DLL并开多线程

VS2015中建立dll工程

1. 文件——>新建项目——>模板——>Visual C++——>MFC——>MFC DLL

输入工程名first_dll

2.下一步——>MFC扩展DLL

3.建立first_dll.h头文件

#pragma once
#ifndef __FIRST_DLL_H__
#define __FIRST_DLL_H__
#include "iostream"
#include "string"
#include "thread"
#include "mutex"

using namespace std;

class Student
{
public:
	void setMyAge(int age);
	void setMyName(char *name);
	void subFunc();
	void startThread();

private:
	int  age = 0;
	char name[32];
	static volatile int mId;
	static std::mutex   mMutex;

};

#endif

在first_dll.cpp中输入

// first_dll.cpp : 定义 DLL 的初始化例程。
//

#include "stdafx.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


#include "iostream"
#include "first_dll.h"

using namespace std;

volatile int Student::mId = 0;
std::mutex   Student::mMutex;

void Student::setMyAge(int age) {
	std::cout << "Student::mySetAge" << std::endl;
}

void Student::setMyName(char *name) {
	std::cout << "Student::mySetName " << name << std::endl;
	std::string is = "can not use string";
	std::cout << "Student::mySetName is = " << is.c_str() << std::endl;
}

void Student::subFunc() {
	int id = mId++;
	volatile int count = 0;
	while ( (count++) < 5) {
		mMutex.lock();
		std::string text = "idx[" + std::to_string(id) + "]" + std::to_string(count);
		std::cout << text << std::endl;
		mMutex.unlock();
		this_thread::sleep_for(chrono::milliseconds(1000)); //延时1秒
	}
}

void Student::startThread() {

	for (int i = 0; i < 4; i++)
	{
		//std::thread t(callback, i);
		//t.detach();

		std::thread t(&Student::subFunc, this);
		t.detach();
	}
}

将first_dll.h中的函数都注册到first_dll.def中

; first_dll.def : 声明 DLL 的模块参数。

LIBRARY

EXPORTS
    ; 此处可以是显式导出
	setMyAge
	setMyName
	subFunc
	startThread

点击F5生成first_dll.dll和first_dll.lib

二:另建MFC对话框工程myserver

1.文件——>新建项目——>模板——>Visual c++——>MFC——> MFC应用程序

输入工程名称myserver

创建给予对话框的程序

在myserver项目的“解决方案” 上右键——>添加——>添加现有项目——>选到first_dll.vcxproj——>打开

就将first_dll工程与myserver对话框工程结合起来

右键myserver工程——>属性——>配置属性——>c/c++——>常规——>附加包含目录——>编辑

将first_dll的代码目录添加到myserver的包含目录中:

..\..\first_dll\first_dll

在myserver.cpp中添加代码,调用first_dll中代码。包含dll调用与c++11的多线程部分知识。注意HS_ADD_CODE中的代码。


// myserver.cpp : 定义应用程序的类行为。
//

#include "stdafx.h"
#include "myserver.h"
#include "myserverDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


#include "GDefine.h"
#include "iostream"
using namespace std;


#if HS_ADD_CODE
#include "first_dll.h"
#pragma comment(lib, "../Debug/first_dll.lib")
#endif


// CmyserverApp

BEGIN_MESSAGE_MAP(CmyserverApp, CWinApp)
	ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()


// CmyserverApp 构造

CmyserverApp::CmyserverApp()
{
	// 支持重新启动管理器
	m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;

	// TODO: 在此处添加构造代码,
	// 将所有重要的初始化放置在 InitInstance 中
}


// 唯一的一个 CmyserverApp 对象

CmyserverApp theApp;


// CmyserverApp 初始化

BOOL CmyserverApp::InitInstance()
{
	// 如果一个运行在 Windows XP 上的应用程序清单指定要
	// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
	//则需要 InitCommonControlsEx()。  否则,将无法创建窗口。
	INITCOMMONCONTROLSEX InitCtrls;
	InitCtrls.dwSize = sizeof(InitCtrls);
	// 将它设置为包括所有要在应用程序中使用的
	// 公共控件类。
	InitCtrls.dwICC = ICC_WIN95_CLASSES;
	InitCommonControlsEx(&InitCtrls);

	CWinApp::InitInstance();


	AfxEnableControlContainer();

	// 创建 shell 管理器,以防对话框包含
	// 任何 shell 树视图控件或 shell 列表视图控件。
	CShellManager *pShellManager = new CShellManager;

	// 激活“Windows Native”视觉管理器,以便在 MFC 控件中启用主题
	CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));

	// 标准初始化
	// 如果未使用这些功能并希望减小
	// 最终可执行文件的大小,则应移除下列
	// 不需要的特定初始化例程
	// 更改用于存储设置的注册表项
	// TODO: 应适当修改该字符串,
	// 例如修改为公司或组织名
	SetRegistryKey(_T("应用程序向导生成的本地应用程序"));

#if HS_ADD_CODE
#pragma warning(disable:4996)
	AllocConsole();
	freopen("CONOUT$", "w", stdout);
	std::cout << "user std::cout print." << std::endl;
	printf("user printf print str %d", 729);

	Student st;
	st.setMyName("your name ");
	st.startThread();

#endif

	CmyserverDlg dlg;
	m_pMainWnd = &dlg;
	INT_PTR nResponse = dlg.DoModal();
	if (nResponse == IDOK)
	{
		// TODO: 在此放置处理何时用
		//  “确定”来关闭对话框的代码
	}
	else if (nResponse == IDCANCEL)
	{
		// TODO: 在此放置处理何时用
		//  “取消”来关闭对话框的代码
	}
	else if (nResponse == -1)
	{
		TRACE(traceAppMsg, 0, "警告: 对话框创建失败,应用程序将意外终止。\n");
		TRACE(traceAppMsg, 0, "警告: 如果您在对话框上使用 MFC 控件,则无法 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。\n");
	}

#if HS_ADD_CODE
	FreeConsole();
#endif
	// 删除上面创建的 shell 管理器。
	if (pShellManager != NULL)
	{
		delete pShellManager;
	}

#ifndef _AFXDLL
	ControlBarCleanUp();
#endif

	// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
	//  而不是启动应用程序的消息泵。
	return FALSE;
}

myserver工程上按F5,编译运行。

运行结果:

user std::cout print.
user printf print str 729Student::mySetName your name
Student::mySetName is = can not use string
idx[0]1
idx[1]1
idx[2]1
idx[3]1
idx[3]2
idx[1]2
idx[2]2
idx[0]2
idx[3]3
idx[1]3
idx[0]3
idx[2]3
idx[1]4
idx[3]4
idx[2]4
idx[0]4
idx[1]5
idx[3]5
idx[0]5
idx[2]5

完毕

猜你喜欢

转载自blog.csdn.net/wulong710/article/details/81811482