在C++中调用DLL中的函数(3) 您所在的位置:网站首页 组态王自定义函数调用DLL 在C++中调用DLL中的函数(3)

在C++中调用DLL中的函数(3)

2023-08-14 15:32| 来源: 网络整理| 查看: 265

1.dll的优点

代码复用是提高软件开发效率的重要途径。一般而言,只要某部分代码具有通用性,就可将它构造成相对独立的功能模块并在之后的项目中重复使用。比较常见的例子是各种应用程序框架,ATL、MFC等,它们都以源代码的形式发布。由于这种复用是“源码级别”的,源代码完全暴露给了程序员,因而称之为“白盒复用”。“白盒复用”的缺点比较多,总结起来有4点。  暴露了源代码;多份拷贝,造成存储浪费;  容易与程序员的“普通”代码发生命名冲突;  更新功能模块比较困难,不利于问题的模块化实现;  实际上,以上4点概括起来就是“暴露的源代码”造成“代码严重耦合”。为了弥补这些不足,就提出了“二进制级别”的代码复用。使用二进制级别的代码复用一定程度上隐藏了源代码,对于缓解代码耦合现象起到了一定的作用。这样的复用被称为“黑盒复用”。 

说明:实现“黑盒复用”的途径不只dll一种,静态链接库甚至更高级的COM组件都是。

2.dll的创建

参考程序原文:http://msdn.microsoft.com/zh-cn/library/ms235636.aspx 

新建“Win32项目”,选择应用程序类型为"DLL”,其他默认。添加头文件testdll.h

 //testdll.h

#ifdef TESTDLL_EXPORTS  #define TESTDLL_API __declspec(dllexport)   #else  #define TESTDLL_API __declspec(dllimport)   #endif  namespace MathFuncs  {      // This class is exported from the testdll.dll      class MyMathFuncs      {      public:           // Returns a + b          static TESTDLL_API double Add(double a, double b);

        // Returns a - b          static TESTDLL_API double Subtract(double a, double b);

        // Returns a * b          static TESTDLL_API double Multiply(double a, double b);

        // Returns a / b          // Throws const std::invalid_argument& if b is 0          static TESTDLL_API double Divide(double a, double b);    };  }

 当定义了符号TESTDLL_EXPORTS,TESTDLL_API被设置为 __declspec(dllexport) 修饰符, This modifier enables the function to be exported by the DLL so that it can be used by other applications。若未定义则TESTDLL_API被设置为__declspec(dllimport),This modifier enables the compiler to optimize the importing of the function from the DLL for use in other applications。当DLL项目生成时,TESTDLL_EXPORTS默认是定义的,所以默认设置的是__declspec(dllexport) 修饰符。

添加cpp文件

 // testdll.cpp : 定义 DLL 应用程序的导出函数。

#include "stdafx.h"#include "testdll.h"  #include   using namespace std;  

namespace MathFuncs  {      double MyMathFuncs::Add(double a, double b)      {          return a + b;      }  

    double MyMathFuncs::Subtract(double a, double b)      {          return a - b;      }  

    double MyMathFuncs::Multiply(double a, double b)      {          return a * b;      }  

    double MyMathFuncs::Divide(double a, double b)      {          if (b == 0)          {              throw invalid_argument("b cannot be zero!");          }          return a / b;      }  }

编译就会生成对应的dll文件,同时也会生成对应的lib文件。 

注意:a.DLL中导出函数的声明有两种方式:在函数声明中加上__declspec(dllexport);采用模块定义(.def)文件声明。详见:http://www.cnblogs.com/enterBeijingThreetimes/archive/2010/08/04/1792099.html  b.对于C文件创建dll时或者想使用C编译器创建dll时,建议使用 extern “C” 标志,参见extern "C"的简单解析(在C++中调用DLL中的函数(1))

 3.dll的调用

 应用程序使用DLL可以采用两种方式:一种是隐式链接(调用),另一种是显式链接。在使用DLL之前首先要知道DLL中函数的结构信息。VS在VC\bin目录下提供了一个名为Dumpbin.exe的小程序,用它可以查看DLL文件中的函数结构。两种的对比详见:http://blog.sina.com.cn/s/blog_53004b4901009h3b.html 

隐式链接采用静态加载的方式,比较简单,需要.h、.lib、.dll三件套。。新建“控制台应用程序”或“空项目”配置如下:(非常关键)

项目->属性->配置属性->VC++ 目录-> 在“包含目录”里添加头文件testdll.h所在的目录

项目->属性->配置属性->VC++ 目录-> 在“库目录”里添加头文件testdll.lib所在的目录

项目->属性->配置属性->链接器->输入-> 在“附加依赖项”里添加“testdll.lib”(若有多个 lib 则以空格隔开)

添加cpp文件

 //mydll.cpp

#include   #include "testdll.h"  using namespace std;  

int main()  {      double a = 7.4;      int b = 99;  

    cout 



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有