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
完毕