参考了大佬的文章

首先,体会一下静态编译:

创建Win32Project,选DLL,添加一个.h和.cpp文件

点击生成解决方案,然后去debug目录下拷贝.lib和.h文件。

新建一个控制台程序,添加一个main.cpp,效果如下:

(也可以在vs工具栏里添加,不过写代码更快更易懂方便)

静态编译部分到此结束。

以下是动态编译:

创建win32动态dll项目,添加.h和.cpp文件

在同一个工作环境下添加另一个win控制台应用程序,添加main文件如下

这样以后就可以调用了,DLL内的函数分为两种:

  (1)DLL导出函数,可供应用程序调用;

  (2) DLL内部函数,只能在DLL程序使用,应用程序无法调用它们。

以上就是动态链接库内容,编写dll时还可以添加一个.def文件,专门用于描述导出什么函数作为接口,如下:

在之前dll的.h和.cpp基础上作改动:(头文件里可以不用声明deal函数)

以上全部内容,手把手跟着做就可以,优缺点设计原因自己解释。

DLL的静态调用:
(与动态调用的不同点:编译过程中就通过lib文件向exe文件中导入函数的信息,所以就不存在运行时再LoadLibrary)

(与普通函数的不同点:普通函数调用查函数表找地址运行就好,DLL函数查表得dll内存中位置及该函数序号,然后找dll调用该函数。ps:会有DllMain函数的调用,在该进程/线程开始及结束时)

总而言之,静态调用相对方便,windows帮了不少忙,动态调用很麻烦,但灵活性高(运行效率高)

  (1)告诉编译器与DLL相对应的.lib文件所在的路径及文件名,#pragma comment(lib,"dllTest.lib")就是起这个作用。

  程序员在建立一个DLL文件时,连接器会自动为其生成一个对应的.lib文件,该文件包含了DLL 导出函数的符号名及序号(并不含有实际的代码)。在应用程序里,.lib文件将作为DLL的替代文件参与编译。

  (2)声明导入函数,extern "C" __declspec(dllimport) add(int x,int y)语句中的__declspec(dllimport)发挥这个作用。

  静态调用方式不再需要使用系统API来加载、卸载DLL以及获取DLL中导出函数的地址。这是因为,当程序员通过静态链接方式编译生成应用程序时,应用程序中调用的与.lib文件中导出符号相匹配的函数符号将进入到生成的EXE 文件中,.lib文件中所包含的与之对应的DLL文件的文件名也被编译器存储在 EXE文件内部。当应用程序运行过程中需要加载DLL文件时,Windows将根据这些信息发现并加载DLL,然后通过符号名实现对DLL 函数的动态链接。这样,EXE将能直接通过函数名调用DLL的输出函数,就象调用程序内部的其他函数一样。

关于DllMain函数我觉得百度百科的这一篇很详尽

我在win32 dll项目.cpp文件里声明DllMain函数,在vs项目属性-->C/C++预编译器去掉_USRDLL一项,再自己写DllMain如下

DllMain的官方声明如下:

BOOL WINAPI DllMain(
  _In_ HINSTANCE hinstDLL, // 指向自身的句柄
  _In_ DWORD fdwReason, // 调用原因
  _In_ LPVOID lpvReserved // 隐式加载和显式加载
);
// 以上内容来自MSDN

关于其他语言调用DLL

 #ifndef LIB_H
#define LIB_H
int /*__stdcall*/ add(int x, int y); #endif // LIB

关于调用DLL中的全局变量

/*DLL项目部分*/

//DLL.h
#ifndef LIB_H
#define LIB_H
extern "C" int /*__stdcall*/ add(int x, int y);
extern "C" int dllGlobalVar; #endif // LIB //DLL.cpp
#include "WinDll.h"
#include <Windows.h>
#include <stdio.h> int dllGlobalVar = ; int deal(int x, int y){
return - x - y;
} int /*__stdcall*/ add(int x, int y)
{
return deal(x, y);
} BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
printf("procss attach");
dllGlobalVar = ;
break;
case DLL_PROCESS_DETACH:
printf("procss detach, global var is%d\n", dllGlobalVar);
dllGlobalVar = ;
break;
case DLL_THREAD_ATTACH:
printf("thread attach");
break;
case DLL_THREAD_DETACH:
printf("thread detach");
break;
default:
printf("can't default");
}
return TRUE;
} /* .def文件
LIBRARY WinDll EXPORTS
add @ 1
dllGlobalVar DATA
*/ /*控制台程序部分*/ //main.cpp
#include <stdio.h>
#include <Windows.h>
#pragma comment(lib, "..\\Debug\\WinDll.lib") extern "C" int __declspec(dllimport) dllGlobalVar;
extern "C" int __declspec(dllimport) add(int, int); int main(int argc, char **argv)
{
printf("\ndllGLobalVar:%d\n", dllGlobalVar);
dllGlobalVar = ; return ;
}

以上即C代码导出dll的全部内容,下面进入到C++导出类:

懒得写了,C++类的导出和C差不多,类的声明如下

#ifndef POINT_H
#define POINT_H
#ifdef DLL_FILE
class __declspec(dllexport) point //导出类point
#else
class __declspec(dllimport) point //导入类point
#endif
{
public:
float y;
float x;
point();
point(float x_coordinate, float y_coordinate);
}; #endif

这样的话生成lib和dll文件以后拷到需要的工程目录下,

#pragma comment(lib, "path")

一句就可以了。

例如OpenCV库,就需要在QT的pro文件里写上

INCLUDEPATH += D:/opencv/build/include

CONFIG(debug, debug|release): {
LIBS += -LD:/opencv/build/x64/vc12/lib \
-lopencv_core2413d \
-lopencv_imgproc2413d \
-lopencv_highgui2413d \
-lopencv_ml2413d \
-lopencv_video2413d \
-lopencv_features2d2413d \
-lopencv_calib3d2413d \
-lopencv_objdetect2413d \
-lopencv_contrib2413d \
-lopencv_legacy2413d \
-lopencv_flann2413d
} else:CONFIG(release, debug|release): {
LIBS += -LD:/opencv/build/x64/vc12/lib \
-lopencv_core2413 \
-lopencv_imgproc2413 \
-lopencv_highgui2413 \
-lopencv_ml2413 \
-lopencv_video2413 \
-lopencv_features2d2413 \
-lopencv_calib3d2413 \
-lopencv_objdetect2413 \
-lopencv_contrib2413 \
-lopencv_legacy2413 \
-lopencv_flann2413
}

目的就是导入库文件来进行静态链接,可见我几乎每天都在用但是今天才发现。

类的动态编译也一样,略。

关于DLL的方面告一小结,接下来要去整MFC了。

-------------2018.01.11----------------

在vs2013下手把手创建/调用dll的更多相关文章

  1. VS2013环境生成和调用DLL动态链接库

    http://blog.csdn.net/u010273652/article/details/25514577 创建动态库方法: 创建动态库是生成 .dll .lib 两个个文件 文件 -> ...

  2. VS2013 c++ 生成和调用DLL动态链接库(.def 方法已验证OK)

    转载:https://blog.csdn.net/zhunianguo/article/details/52294339 .def 方法 创建动态库方法: 创建动态库是生成 .dll .lib 两个个 ...

  3. VS2013 C++ 生成与调用DLL(动态链接库) 需要验证

    转载:https://blog.csdn.net/s978697043/article/details/82429802 一.创建动态链接库(生成.dll .lib 两个文件) 文件→新建→项目 选择 ...

  4. 在VC中创建并调用DLL

    转自:http://express.ruanko.com/ruanko-express_45/technologyexchange6.html 一.DLL简介 1.什么是DLL? 动态链接库英文为DL ...

  5. VC++创建、调用dll的方法步骤

    文章来源:http://www.cnblogs.com/houkai/archive/2013/06/05/3119513.html 代码复用是提高软件开发效率的重要途径.一般而言,只要某部分代码具有 ...

  6. VS2013 C#中调用DLL

    winform界面中,使用C#编程调用DLL过程记录: (1)什么是DLL 动态链接库英文为DLL,是Dynamic Link Library 的缩写形式,DLL 是一个包含可由多个程序同时使用的代码 ...

  7. C++ Builder创建和调用dll中的资源

    程序开发中经常会用到一些图标.图片.光标.声音等,我们称它们为资源(Resource).当多个窗口用到同样的资源时,可以将这些公共的资源放到一个dll文件里调用,这样,由于定位资源比在磁盘中定位文件花 ...

  8. C++在VS下创建、调用dll

    转自:http://www.cnblogs.com/houkai/archive/2013/06/05/3119513.html 目录 1.dll的优点 代码复用是提高软件开发效率的重要途径.一般而言 ...

  9. QT创建与调用Dll方法(包括类成员)--显式调用

    看网上的好多关于QT调用Dll的方法,大部分都是调用函数的,并没有调用C++类成员的情况,即使是有,比如说: 使用Qt编写模块化插件式应用程序 Qt 一步一步实现dll调用(附源码)---(这一篇里没 ...

随机推荐

  1. Android官方命令深入分析之绘制9-patch

    9-patch是一个所见即所得的编辑器,允许你创建可以自动更改大小适应屏幕的bitmap图像.被选中的部分可以水平或垂直的进行缩放. 下面是使用9-patch工具创建一个9-patch图像的实例,首先 ...

  2. TOMCAT数据源连接配置

    /* *本文档简单介绍系统使用TOMCAT6.0数据源方式连接数据库的配置方法: *1,系统环境:  gdczsam4.0 + Tomcat6.0 + JDK1.5 + SQL Server2008 ...

  3. ArrayList与Vector的区别

    ArrayList与Vector的区别 相同 这两个类都实现了List接口. 他们都是有序集合. 不同 ArrayList实现不是同步的,Vector实现是同步的. ArrayList与Vector都 ...

  4. DB 查询分析器 方便地创建DB2自定义函数

    DB 查询分析器 方便地创建DB2自定义函数                           马根峰            (广东联合电子服务股份有限公司, 广州 510300) 摘要       ...

  5. 将Ext JS 5应用程序导入Web项目以及实现本地化

    在Ext JS 5,使用了新的脚本和样式加载方式,这对于将应用程序导入到Web项目中产生了点小麻烦.而对于本地化文件的导入,也采用了新的方式,本文将一一解答这些问题. 将Ext JS 5应用程序导入W ...

  6. (四十四)TabBarController和NagivationController配合

    如果既要使用TabBar分页,又要使用Nagivation导航,那么只能是TabBar为根,Nagivation为TabBar子视图,每一个TabBar对应一个Nagivation导航的一系列页面. ...

  7. python检测变量是否有定义(即使用前检查是否定义好)

    http://www.cnblogs.com/starspace/archive/2008/12/03/1347007.html 第一种方法: 'var' in locals().keys() 第二种 ...

  8. python发送post请求

    urllib2.urlopen() urlib2是使用各种协议完成打开url的一个扩展包.最简单的使用方式是调用urlopen方法,比如 def urlopen(url, data=None, tim ...

  9. css之盒子模型案例

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. HTML DOCTYPE 的重要性

    定义和用法 <!DOCTYPE> 声明必须是 HTML 文档的第一行,位于 <html> 标签之前. <!DOCTYPE> 声明不是 HTML 标签:它是指示 we ...