在vs2013下手把手创建/调用dll
参考了大佬的文章
首先,体会一下静态编译:
创建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的更多相关文章
- VS2013环境生成和调用DLL动态链接库
http://blog.csdn.net/u010273652/article/details/25514577 创建动态库方法: 创建动态库是生成 .dll .lib 两个个文件 文件 -> ...
- VS2013 c++ 生成和调用DLL动态链接库(.def 方法已验证OK)
转载:https://blog.csdn.net/zhunianguo/article/details/52294339 .def 方法 创建动态库方法: 创建动态库是生成 .dll .lib 两个个 ...
- VS2013 C++ 生成与调用DLL(动态链接库) 需要验证
转载:https://blog.csdn.net/s978697043/article/details/82429802 一.创建动态链接库(生成.dll .lib 两个文件) 文件→新建→项目 选择 ...
- 在VC中创建并调用DLL
转自:http://express.ruanko.com/ruanko-express_45/technologyexchange6.html 一.DLL简介 1.什么是DLL? 动态链接库英文为DL ...
- VC++创建、调用dll的方法步骤
文章来源:http://www.cnblogs.com/houkai/archive/2013/06/05/3119513.html 代码复用是提高软件开发效率的重要途径.一般而言,只要某部分代码具有 ...
- VS2013 C#中调用DLL
winform界面中,使用C#编程调用DLL过程记录: (1)什么是DLL 动态链接库英文为DLL,是Dynamic Link Library 的缩写形式,DLL 是一个包含可由多个程序同时使用的代码 ...
- C++ Builder创建和调用dll中的资源
程序开发中经常会用到一些图标.图片.光标.声音等,我们称它们为资源(Resource).当多个窗口用到同样的资源时,可以将这些公共的资源放到一个dll文件里调用,这样,由于定位资源比在磁盘中定位文件花 ...
- C++在VS下创建、调用dll
转自:http://www.cnblogs.com/houkai/archive/2013/06/05/3119513.html 目录 1.dll的优点 代码复用是提高软件开发效率的重要途径.一般而言 ...
- QT创建与调用Dll方法(包括类成员)--显式调用
看网上的好多关于QT调用Dll的方法,大部分都是调用函数的,并没有调用C++类成员的情况,即使是有,比如说: 使用Qt编写模块化插件式应用程序 Qt 一步一步实现dll调用(附源码)---(这一篇里没 ...
随机推荐
- 套接字输入缓冲装置——InternalInputBuffer
互联网的世界很复杂,信息从一端传向另一端过程也相当复杂,中间可能通过若干个硬件,为了提高发送和接收效率,在发送端及接收端都将引入缓冲区,所以两端的套接字都拥有各自的缓冲区,当然这种缓冲区的引入也带来了 ...
- UNIX环境高级编程——互斥量属性
互斥量具有一些属性,通过修改这些属性可以控制锁的一些行为.缺省的互斥锁属性及其值如下: pshared: PTHREAD_PROCESS_PRIVATE type: ...
- 【一天一道LeetCode】#104. Maximum Depth of Binary Tree
一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 来源:http ...
- TCP/IP入门(4) --应用层
/** 本篇博客由汗青ZJF整理并发布, 转载请注明出处: http://blog.csdn.net/zjf280441589/article/category/1854365 */ TCP/IP中的 ...
- 在go中使用linked channels进行数据广播
在go中使用linked channels进行数据广播 原文在这里(需FQ),为啥想要翻译这篇文章是因为在实际中也碰到过如此的问题,而该文章的解决方式很巧妙,希望对大家有用. 在go中channels ...
- Spring mvc,uploadifive 文件上传实践(转自:https://segmentfault.com/a/1190000004503262)
1.前台页面: 引入js和css 全选复制放进笔记 <link type="text/css" rel="stylesheet" href=&quo ...
- 结构体:探析C#文件方式读写结构体
最近直在研究Net Micro Framework字体文件(tinyfnt)由于tinyfnt文件头部有段描述数据所以很想 定义个结构体像VC样直接从文件中读出来省得用流个个解析很是麻烦 没有想到在中 ...
- 【算法导论】最小生成树之Prime法
关于最小生成树的概念,在前一篇文章中已经讲到,就不在赘述了.下面介绍Prime算法: 其基本思想为:从一个顶点出发,选择由该顶点出发的最小权值边,并将该边的另一个顶点包含进来,然后找出 ...
- 为神马精确Sprite的碰撞形状不通过简单的放大Sprite的尺寸来解决?
原因是SoftBodyDrawNode的绘制代码中已经没有完整的,一体化的(incorporate)缩放,旋转或者甚至是精灵的位置(scale,rotation,or even the sprite' ...
- Orientation Auto Rotation旋转屏幕crash问题(Unity3D开发之十四)
猴子原创,欢迎转载.转载请注明: 转载自Cocos2Der-CSDN,谢谢! 原文地址: http://blog.csdn.net/cocos2der/article/details/44133127 ...