首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >VC++的DLL应用(含Demo演示)

VC++的DLL应用(含Demo演示)

作者头像
用户1170933
发布于 2022-05-10 06:33:38
发布于 2022-05-10 06:33:38
1.1K00
代码可运行
举报
文章被收录于专栏:python开发者python开发者
运行总次数:0
代码可运行

VC++的DLL应用(含Demo演示)

作者:一点一滴的Beer http://beer.cnblogs.com/

      在大学大一的时候学的是C,然后后来大二的时候专业又开了C++这个课程,然后再后来自己又自学了一点VC++,大三的时候也试着编写过一个MFC的最简单的窗口程序。到大四的时候,自己又做了一个GIS的项目,是用C#.NET来编写的,然后发现C#上手好容易,而且还大部分语法规则都沿用了C,C++的习惯,于是觉得C++实在是没有一点优势可言啊。但这个暑假的实习经历又改变了我的观点:C++在写窗口程序虽然麻烦,但是却什么能做,而且对比C#来说,对运行环境的要求不高,不用像C#程序在安装之前还要安装100M多的运行.NET环境。C++和C#各有优缺,目前我对它们俩的定位是:C++用来写一些底层的程序,比如驱动,或者是一些算法类型的函数接口,然后用C#来调用这些接口并进行界面设计。如何函数的实现跨语言呢?显然DLL是个很重要的内容,故在此对VC++的DLL模块进行介绍。

1 用VC创建DLL动态连接库

1.1 创建dll项目

然后选择“一个空的dll工程”,然后点击“确定”便完成了“创建dll项目”的流程。

1.2 为dll项目编写源文件

新建两个文件:dllDemo.h, dllDemo.cpp

在头文件”dllDemo.h”中声明三个接口函数:

extern "C" _declspec(dllexport) int Sum(int a,int b);//加法函数。 extern "C" _declspec(dllexport) int Max(int a, int b);//取较大值函数 extern "C" _declspec(dllexport) int Min(int a, int b);//取较小值函数

然后在“dllDemo.cpp”文件中实现三个接口函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include "dllDemo.h"
extern "C" _declspec(dllexport)int Sum(int a, int b)
{
return a+b;
}
extern "C" _declspec(dllexport)int Max(int a, int b)
{
if(a>=b)return a;
else
return b;
}
extern "C" _declspec(dllexport)int Min(int a, int b)
{
if(a>=b)return b;
else
return a;
}

1.3 生成dll文件

编译源文件,如果没有出现错误提示,那么,在项目文件根目录的Debug文件夹内会生成一个dll文件“dllDemo.dll”。

2 DLL调用

2.1 用C++调用显式链接

新建一个Win32的控制台程序进行显式调用:

1. 新建“dllConsoleEvident”的Win32控制台程序项目

2. 新建cpp文件“dllConsoleEvident.cpp”

3. 将在第一节中,在Debug目录下编译生成的“dllDemo.dll”(显式调用时只需要这一个文件就够了)文件复制到“dllConsoleEvident”项目下的Debug文件夹根目录下

4. 在“dllConsoleEvident.cpp”文件中编写以下代码对dll中的函数进行显式调用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//////////////////////////////////////////////////////////////////////////
//动态加载DLL文件
#include <iostream.h>
#include<windows.h>
void main(void)
{
typedef int(*pMax)(int a,int b);//函数指针
typedef int(*pMin)(int a,int b);
pMax Max=NULL;
pMin Min=NULL;
HINSTANCE hDLL;
hDLL=LoadLibrary("MyDll.dll");//加载动态链接库MyDll.dll文件;
Max=(pMax)GetProcAddress(hDLL,"Max");
Min=(pMin)GetProcAddress(hDLL,"Min");
if (Max)//如果取出函数成功,则执行下面的语句
{
int A=Max(5,8);
cout<<"比较的结果为"<<A;
}
if (Min)
{
int B=Min(5,8);
cout<<"比较的结果为"<<B;
}
FreeLibrary(hDLL);//卸载MyDll.dll文件;
}

2.2 用C++隐式链接(Win32控制台程序)

新建一个Win32控制台程序演示静态调用

1. 利用向导新建“dllConsoleStaticDemo”的空工程

2. 将“dllDemo.dll”和“dllDemo.lib”文件复制到Debug目录下,并在项目中包含“dllDemo.lib”文件(或者),否则会出现dll函数找不到的连接错误

3. 新建“dllConsoleStaticDemo.cpp”文件,并写入如下代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
extern "C"_declspec(dllimport) int Sum(int a,int b);
extern "C"_declspec(dllimport) int Max(int a,int b);
extern "C"_declspec(dllimport) int Min(int a,int b);
#include <iostream.h>
void main()
{
int c=Sum(4,5);
c=Max(5,6);
c=Min(5,6);
cout<<"Hello,dllConsoleTest~!";
}

4.通过断点,可以看到dll函数调用成功

这种方式的静态调用的特点是:在程序一开始执行的时候,就将dll文件全部加载到程序中,不会释放。

2.3 用C++隐式链接(MFC窗口程序)

新建一个MFC基本对话框窗口程序进行调用:

1. 利用向导建立一个MFC基本对话框

2. 将“dllDemo.dll”和”dllDemo.lib”文件复制到本项目的Debug目录下,在VC工作空间的文件视图下面将”dllDemo.lib”添加到项目中

3. 在“dllMfcDemoDlg.h”头文件中的前面对来自外部的dll函数进行声明

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// dllMfcDemoDlg.h : header file
//
#if !defined(AFX_DLLMFCDEMODLG_H__E358B876_D188_48FD_8D83_794309C885A9__INCLUDED_)
#define AFX_DLLMFCDEMODLG_H__E358B876_D188_48FD_8D83_794309C885A9__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
/////////////////////////////////////////////////////////////////////////////
// CDllMfcDemoDlg dialog
extern "C"_declspec(dllimport) int Sum(int a,int b);
extern "C"_declspec(dllimport) int Max(int a,int b);
extern "C"_declspec(dllimport) int Min(int a,int b);
……

4.在窗体界面上,双击“确定”按钮,进入到OnOk()的事件响应函数体,编写调用代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void CDllMfcDemoDlg::OnOK()
{
  // TODO: Add extra validation here
  int c=Sum(4,5);
  c=Max(5,6);
  c=Min(5,6);
  CDialog::OnOK();
}

通过设置断点单步运行就可以看到dll文件中的函数已经被成功调用了。

2.4 用C#跨语言调用

C#控制台程序调用VC++建立一个dll:

1. 用Visual Studio建立一个控制台程序

2. 将“dllDemo.dll”文件复制到项目的Debug目录下面

3. 在“Program.cs”中编写如下代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;//引入dll文件中的函数
namespace ConsoleDllDemo
{
class Program
{
//引入dll文件中的函数
[DllImport("dllDemo.dll")]
private static extern int Sum(int a, int b);
[DllImport("dllDemo.dll")]
private static extern int Max(int a, int b);
[DllImport("dllDemo.dll")]
private static extern int Min(int a, int b);
static void Main(string[] args)
{
int a = Sum(3, 5);
Console.WriteLine(a);
Console.WriteLine(Max(5,10));
Console.WriteLine(Min(12,25));
Console.ReadKey();//要按键才退出。
}
}
}

然后断点单步运行,便可以看到调用函数的结果了。

关于DLL的调用的更详细内容可以参考另外一些文章:

http://dev.firnow.com/course/3_program/c++/cppsl/2008127/97781.html

http://dev.yesky.com/283/2640283_2.shtml

3 dll调试方法

在建立了dll项目后,并写好相应的实现代码,点击“运行”,会弹出现在的对话框:

然后浏览,找到一个调用了此dll文件的执行文件“*.exe”文件,然后就可以对dll文件进行断点调试了。

这个“*.exe”文件可以是任何平台的,C++也可以,C也可以,C#也可以,只要这个执行文件调用了dll文件中的函数即可。

如果想更换调试的“*.exe”文件,可以在“工程-》设置”对话框中的“调试”选项卡进行设置,浏览找到用户需要的“*.exe”文件

说明:以VC++环境中调用此dll为例,运行dllDemo项目,然后会调用“*.exe”文件,如果此exe文件含有源文件,而且刚好在源文件的Debug目录下面,那么,可以同时在exe文件的源文件中设置断点,进行dll和调用dll两个程序的联调。(好像跨语言调用的时候不能进行联调,笔者只在C++互相调用的时候联调成功过,但C#调用的时候没有联调成功,这个问题有待解决)

4. DLL返回数据类型探究

目前写的DLL函数反返回值还仅限于整形,还没有尝试其它特殊类型的返回值。更丰富的返回值类型,还要今后慢慢学习和研究。等回学校了再研究吧。请见后续文章吧。

附件:

VC_dll_Realse.rar中是VC编写DLL并引用DLL的相关源码文件

CShapr_ConsoleDllDemo.rar中是VS2005编写的C#引用VC编写的DLL函数的相关源码文件

https://files.cnblogs.com/beer/VC_dll_Realese.rar

https://files.cnblogs.com/beer/CSharp_ConsoleDllDemo.rar

------------------------------------------------------------------

Author:一点一滴的Beer

Email /Gtalk:dreamzsm@gmail.com

From:http://www.cnblogs.com/beer

Notes:欢迎转贴,但请在页面中加个链接注明出处

Time:2010-8-19

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2010-08-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
c++DLL编程详解
DLL(Dynamic Link Library)的概念,你可以简单的把DLL看成一种仓库,它提供给你一些可以直接拿来用的变量、函数或类。在仓库的发展史上经历了“无库-静态链接库-动态链接库”的时代。 静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib中的指令都被直接包含在最终生成的EXE文件中了。但是若使用DLL,该DLL不必被包含在最终EXE文件中,EXE文件执行时可以“动态”地引用和卸载这个与EXE独立的DLL文件。静态链接库和动态链接库的另外一个区别在于静态链接库
拾点阳光
2018/05/10
2.5K0
c#封装动态库_nginx调用so动态库
一直对动态库的封装理解不是很透彻,虽然之前写过一个Demo,不过并没有真正的理解。所以写下来,帮助自己理解下。
全栈程序员站长
2022/11/14
3K0
c#封装动态库_nginx调用so动态库
VC++DLL动态链接库程序
最近查找了一下VC++中关于编写DLL动态库的资料,主要是导出函数和导出类的编写。因为在实际项目开发中有时需要使用C++编写好DLL接口,控制设备,提供给其他语言如Nodejs、C#等使用。
ccf19881030
2019/07/10
1.5K0
C/C++中动态链接库的创建和调用
古时的风筝
2018/01/08
1.7K0
QT编写DLL给外部程序调用,提供VC/C#/C调用示例(含事件)
最近这阵子,接了个私活,封装一个开发包俗称的SDK给客户调用,查阅了很多人家的SDK,绝大部分用VC编写,而且VC6.0居多,估计也是为了兼容大量的XP用户及IE浏览器,XP自带了VC6.0运行库,所以无需兼带其他DLL即可运行。也发现有些用汇编和C封装的,那估计是高手才能编写啊!那怎么办呢?眼看一星期的交货期要到了,由于本人从来没有写过SDK开发包,心里那个着急啊,赶紧想出了三种处理方案。
用户3519280
2023/07/06
1.1K0
QT编写DLL给外部程序调用,提供VC/C#/C调用示例(含事件)
【编程基础】跟我学创建Windows动态库
如何简单快速创建Win32平台下的动态链接库?但是有的创建出来用C/C++调用时没有问题,但是在其它编程语言调用时可能会出现问题,下面我们就按四个傻瓜式的步骤创建通用的windows动态库过程。 创建空的win32的工程。 添加C/C++头文件内容(MyHead.h): #ifndef __MYHEAD_H__ #define __MYHEAD_H__ #ifndef MY_API #define MY_API extern "C" __declspec(dllimport) #endif 现在添加你想要
程序员互动联盟
2018/03/13
6520
【编程基础】跟我学创建Windows动态库
window 动态库的创建和使用
File--新建---工程--win32 Dynamic-link Library   输入工程名和位置,即可进入动态库界面。
用户4148957
2022/06/14
1.2K0
C# DllImport的用法
大家在实际工作学习C#的时候,可能会问:为什么我们要为一些已经存在的功能(比如Windows中的一些功能,C++中已经编写好的一些方法)要重新编写代码,C#有没有方法可以直接都用这些原本已经存在的功能呢?答案是肯定的,大家可以通过C#中的DllImport直接调用这些功能。 DllImport所在的名字空间 using System.Runtime.InteropServices; MSDN中对DllImportAttribute的解释是这样的:可将该属性应用于方法。DllImportAttribute 属性提供对从非托管 DLL 导出的函数进行调用所必需的信息。作为最低要求,必须提供包含入口点的 DLL 的名称。 DllImport 属性定义如下: namespace System.Runtime.InteropServices {   [AttributeUsage(AttributeTargets.Method)]   public class DllImportAttribute: System.Attribute   {    public DllImportAttribute(string dllName) {…}    public CallingConvention CallingConvention;    public CharSet CharSet;    public string EntryPoint;    public bool ExactSpelling;    public bool PreserveSig;    public bool SetLastError;    public string Value { get {…} }   } }   说明:   1、DllImport只能放置在方法声明上。   2、DllImport具有单个定位参数:指定包含被导入方法的 dll 名称的 dllName 参数。   3、DllImport具有五个命名参数:    a、CallingConvention 参数指示入口点的调用约定。如果未指定 CallingConvention,则使用默认值 CallingConvention.Winapi。    b、CharSet 参数指示用在入口点中的字符集。如果未指定 CharSet,则使用默认值 CharSet.Auto。    c、EntryPoint 参数给出 dll 中入口点的名称。如果未指定 EntryPoint,则使用方法本身的名称。    d、ExactSpelling 参数指示 EntryPoint 是否必须与指示的入口点的拼写完全匹配。如果未指定 ExactSpelling,则使用默认值 false。    e、PreserveSig 参数指示方法的签名应当被保留还是被转换。当签名被转换时,它被转换为一个具有 HRESULT 返回值和该返回值的一个名为 retval 的附加输出参数的签名。如果未指定 PreserveSig,则使用默认值 true。    f、SetLastError 参数指示方法是否保留 Win32″上一错误”。如果未指定 SetLastError,则使用默认值 false。   4、它是一次性属性类。   5、此外,用 DllImport 属性修饰的方法必须具有 extern 修饰符。
全栈程序员站长
2022/07/23
1.2K0
Qt中纯C++项目发布为dll的方法(超详细步骤)
目录 一般创建方法 导出普通函数的方法&调用方法 导出类及其成员函数的方法&调用方法 众所周知,我们可以将C++项目中的类以及函数导出,形成 .dll 文件,以供其他程序使用,下面将说明Qt环境下的使
用户1198337
2018/01/19
2.1K0
Qt中纯C++项目发布为dll的方法(超详细步骤)
Win32编程之静态库编写与使用.动态链接库的编写与使用
  静态库其实就是解决模块开发的一种解决方案.在以前.我们写代码的时候.每个人都可以独立写一个项目.但是现在不行了.一个项目往往要很多人一起去编写.而其中用到的技术就类似于静态库.
IBinary
2022/05/10
8810
Win32编程之静态库编写与使用.动态链接库的编写与使用
exe调用DLL的方式
编写dll时,有个重要的问题需要解决,那就是函数重命名——Name-Mangling。解决方式有两种,一种是直接在代码里解决采用extent”c”、_declspec(dllexport)、#pragma comment(linker, "/export:[Exports Name]=[Mangling Name]"),另一种是采用def文件。
CN_Simo
2020/08/20
2.9K0
c#开发的客户端,如何调用c++开发的sdk dll库
c#客户端不能直接调用c++ dll,需要做2个黏合层把它们连接起来,这里以trtc sdk的dll为例
Tomas7571
2021/05/14
5.7K0
c#开发的客户端,如何调用c++开发的sdk dll库
lib文件和dll文件的区别_dll2lib
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/167993.html原文链接:https://javaforall.cn
全栈程序员站长
2022/09/20
3.3K0
在VS2010上使用C#调用非托管C++生成的DLL文件(图文讲解) 背景
背景      在项目过程中,有时候你需要调用非C#编写的DLL文件,尤其在使用一些第三方通讯组件的时候,通过C#来开发应用软件时,就需要利用DllImport特性进行方法调用。本篇文章将引导你快速
庞小明
2018/03/09
3.1K0
在VS2010上使用C#调用非托管C++生成的DLL文件(图文讲解) 背景
InlineHook实践
  InlineHook是一种指令级的函数hook方式,通过直接修改运行时内存的方式替换指令,完全手工的完成hook及跳回操作,理论上可以实现任意位置的hook。平时使用Frida进行Native hook实际上也是用的InlineHook的原理。
大A
2023/03/23
3820
12、动态链接库,dll
动态链接库通常都不能直接运行,也不能接收消息。它们是一些独立的文件,其中包含能被可执行程序或其它DLL调用来完成某项工作的函数。只有在其它模块调用动态链接库中的函数时,它才发挥作用。
全栈程序员站长
2022/07/05
1K0
12、动态链接库,dll
VS2010编写动态链接库DLL和单元测试,转让DLL测试的正确性
本文将创建一个简单的动态库-link,谱写控制台应用程序使用该动态链接库,该动态链接库为“JAVA调用动态链接库DLL之JNative学习”中使用的DLL,仅仅是项目及文件名不同。
全栈程序员站长
2022/07/05
1.5K0
VS2010编写动态链接库DLL和单元测试,转让DLL测试的正确性
VS2015中用C++创建MFC DLL动态库「建议收藏」
2 点击下一步,在应用程序设置里选择带静态链接的MFC规则,这个主要为了以静态库的形式生成MFC dll,便于动态库可以移植到其它编程语言或者其它计算机系统里调用。
全栈程序员站长
2022/11/11
2.1K0
VS2017生成DLL(C语言)文件并在C#中使用
下面我们将在VS2017生成dll文件(动态库文件)和lib文件(静态库文件),这里以C语言为例,用最简单的例子,来让读者了解如何生成dll文件(动态库文件)
zls365
2021/01/28
2.5K0
dll生成和使用
dll文件的编译生成 创建项目Win32控制台应用程序 创建项目1.png 创建项目2.png 配置属性 项目/属性 配置属性.png
用户2929716
2018/08/23
1.3K0
dll生成和使用
相关推荐
c++DLL编程详解
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验